summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--cmake/QtBuildHelpers.cmake3
-rw-r--r--cmake/QtBuildInformation.cmake5
-rw-r--r--cmake/QtProcessConfigureArgs.cmake29
-rw-r--r--cmake/QtPublicSbomCommonGenerationHelpers.cmake668
-rw-r--r--cmake/QtPublicSbomCycloneDXHelpers.cmake382
-rw-r--r--cmake/QtPublicSbomDepHelpers.cmake75
-rw-r--r--cmake/QtPublicSbomGenerationCycloneDXHelpers.cmake425
-rw-r--r--cmake/QtPublicSbomGenerationHelpers.cmake426
-rw-r--r--cmake/QtPublicSbomHelpers.cmake568
-rw-r--r--cmake/QtPublicSbomLicenseHelpers.cmake18
-rw-r--r--cmake/QtPublicSbomOpsHelpers.cmake324
-rw-r--r--cmake/QtPublicSbomPurlHelpers.cmake79
-rw-r--r--cmake/QtPublicSbomPythonHelpers.cmake19
-rw-r--r--cmake/QtPublicSbomQtEntityHelpers.cmake7
-rw-r--r--cmake/QtSbomHelpers.cmake98
-rw-r--r--cmake/QtTargetHelpers.cmake19
-rw-r--r--cmake/QtWrapperScriptHelpers.cmake18
-rw-r--r--cmake/configure-cmake-mapping.md16
-rw-r--r--coin/instructions/prepare_building_env.yaml15
-rw-r--r--coin/instructions/vxworks_test_env_setup.yaml1
-rw-r--r--config_help.txt2
-rw-r--r--doc/global/config.qdocconf3
-rw-r--r--examples/widgets/doc/images/treemodel-structure.svg134
-rw-r--r--licenseRule.json5
-rw-r--r--src/3rdparty/double-conversion/0001-fix-decimal_point-initialization-to-suppress-warning.patch40
-rw-r--r--src/3rdparty/double-conversion/REUSE.toml2
-rw-r--r--src/3rdparty/double-conversion/double-conversion/double-to-string.cc3
-rw-r--r--src/3rdparty/pcre2/AUTHORS.md16
-rw-r--r--src/3rdparty/pcre2/CMakeLists.txt1
-rw-r--r--src/3rdparty/pcre2/LICENCE.md9
-rw-r--r--src/3rdparty/pcre2/LICENSE-SLJIT (renamed from src/3rdparty/pcre2/LICENCE-SLJIT)0
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorCore.c48
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitConfigInternal.h68
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.c427
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.h249
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_32.c286
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_64.c298
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_T2_32.c293
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeLOONGARCH_64.c293
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_32.c9
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_64.c13
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_common.c294
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_32.c4
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_64.c8
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_common.c326
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_32.c34
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_64.c167
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_common.c1716
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeS390X.c602
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_32.c62
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_64.c31
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_common.c360
-rw-r--r--src/3rdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c89
-rwxr-xr-xsrc/3rdparty/pcre2/import_from_pcre2_tarball.sh9
-rw-r--r--src/3rdparty/pcre2/qt_attribution.json19
-rw-r--r--src/3rdparty/pcre2/src/pcre2.h52
-rw-r--r--src/3rdparty/pcre2/src/pcre2_auto_possess.c20
-rw-r--r--src/3rdparty/pcre2/src/pcre2_chartables.c4
-rw-r--r--src/3rdparty/pcre2/src/pcre2_chkdint.c8
-rw-r--r--src/3rdparty/pcre2/src/pcre2_compile.c1360
-rw-r--r--src/3rdparty/pcre2/src/pcre2_compile.h116
-rw-r--r--src/3rdparty/pcre2/src/pcre2_compile_cgroup.c632
-rw-r--r--src/3rdparty/pcre2/src/pcre2_compile_class.c60
-rw-r--r--src/3rdparty/pcre2/src/pcre2_config.c28
-rw-r--r--src/3rdparty/pcre2/src/pcre2_context.c23
-rw-r--r--src/3rdparty/pcre2/src/pcre2_dfa_match.c114
-rw-r--r--src/3rdparty/pcre2/src/pcre2_error.c45
-rw-r--r--src/3rdparty/pcre2/src/pcre2_extuni.c7
-rw-r--r--src/3rdparty/pcre2/src/pcre2_find_bracket.c5
-rw-r--r--src/3rdparty/pcre2/src/pcre2_internal.h434
-rw-r--r--src/3rdparty/pcre2/src/pcre2_intmodedep.h119
-rw-r--r--src/3rdparty/pcre2/src/pcre2_jit_char_inc.h26
-rw-r--r--src/3rdparty/pcre2/src/pcre2_jit_compile.c411
-rw-r--r--src/3rdparty/pcre2/src/pcre2_jit_match_inc.h (renamed from src/3rdparty/pcre2/src/pcre2_jit_match.c)12
-rw-r--r--src/3rdparty/pcre2/src/pcre2_jit_misc_inc.h (renamed from src/3rdparty/pcre2/src/pcre2_jit_misc.c)2
-rw-r--r--src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h354
-rw-r--r--src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h808
-rw-r--r--src/3rdparty/pcre2/src/pcre2_maketables.c62
-rw-r--r--src/3rdparty/pcre2/src/pcre2_match.c293
-rw-r--r--src/3rdparty/pcre2/src/pcre2_match_data.c5
-rw-r--r--src/3rdparty/pcre2/src/pcre2_newline.c4
-rw-r--r--src/3rdparty/pcre2/src/pcre2_ord2utf.c12
-rw-r--r--src/3rdparty/pcre2/src/pcre2_pattern_info.c8
-rw-r--r--src/3rdparty/pcre2/src/pcre2_script_run.c5
-rw-r--r--src/3rdparty/pcre2/src/pcre2_serialize.c6
-rw-r--r--src/3rdparty/pcre2/src/pcre2_string_utils.c40
-rw-r--r--src/3rdparty/pcre2/src/pcre2_study.c89
-rw-r--r--src/3rdparty/pcre2/src/pcre2_substitute.c246
-rw-r--r--src/3rdparty/pcre2/src/pcre2_substring.c17
-rw-r--r--src/3rdparty/pcre2/src/pcre2_tables.c112
-rw-r--r--src/3rdparty/pcre2/src/pcre2_ucd.c7
-rw-r--r--src/3rdparty/pcre2/src/pcre2_ucptables_inc.h (renamed from src/3rdparty/pcre2/src/pcre2_ucptables.c)2
-rw-r--r--src/3rdparty/pcre2/src/pcre2_util.h51
-rw-r--r--src/3rdparty/pcre2/src/pcre2_valid_utf.c5
-rw-r--r--src/3rdparty/pcre2/src/pcre2_xclass.c10
-rw-r--r--src/3rdparty/sha3/qt_attribution.json2
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java23
-rw-r--r--src/assets/CMakeLists.txt6
-rw-r--r--src/assets/downloader/CMakeLists.txt32
-rw-r--r--src/assets/downloader/assetdownloader.cpp592
-rw-r--r--src/assets/downloader/assetdownloader.h118
-rw-r--r--src/assets/downloader/tasking/barrier.cpp54
-rw-r--r--src/assets/downloader/tasking/barrier.h126
-rw-r--r--src/assets/downloader/tasking/concurrentcall.h119
-rw-r--r--src/assets/downloader/tasking/conditional.cpp91
-rw-r--r--src/assets/downloader/tasking/conditional.h142
-rw-r--r--src/assets/downloader/tasking/networkquery.cpp63
-rw-r--r--src/assets/downloader/tasking/networkquery.h74
-rw-r--r--src/assets/downloader/tasking/qprocesstask.cpp280
-rw-r--r--src/assets/downloader/tasking/qprocesstask.h89
-rw-r--r--src/assets/downloader/tasking/tasking_global.h25
-rw-r--r--src/assets/downloader/tasking/tasktree.cpp3701
-rw-r--r--src/assets/downloader/tasking/tasktree.h757
-rw-r--r--src/assets/downloader/tasking/tasktreerunner.cpp45
-rw-r--r--src/assets/downloader/tasking/tasktreerunner.h63
-rw-r--r--src/assets/downloader/tasking/tcpsocket.cpp57
-rw-r--r--src/assets/downloader/tasking/tcpsocket.h65
-rw-r--r--src/corelib/CMakeLists.txt4
-rw-r--r--src/corelib/Qt6AndroidMacros.cmake183
-rw-r--r--src/corelib/compat/removed_api.cpp7
-rw-r--r--src/corelib/configure.cmake2
-rw-r--r--src/corelib/doc/images/javaiterators1.svg59
-rw-r--r--src/corelib/doc/images/javaiterators2.svg63
-rw-r--r--src/corelib/doc/src/java-style-iterators.qdoc4
-rw-r--r--src/corelib/doc/src/objectmodel/bindableproperties.qdoc4
-rw-r--r--src/corelib/global/qassert.cpp19
-rw-r--r--src/corelib/io/qfile.h29
-rw-r--r--src/corelib/io/qfiledevice.h32
-rw-r--r--src/corelib/io/qiooperation_p_p.h12
-rw-r--r--src/corelib/io/qlockfile.cpp9
-rw-r--r--src/corelib/io/qsavefile.cpp20
-rw-r--r--src/corelib/io/qsavefile.h14
-rw-r--r--src/corelib/itemmodels/qrangemodel.cpp14
-rw-r--r--src/corelib/itemmodels/qrangemodel_impl.h70
-rw-r--r--src/corelib/kernel/qassociativeiterable.cpp10
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp2
-rw-r--r--src/corelib/kernel/qcoreapplication.h2
-rw-r--r--src/corelib/kernel/qpermissions.cpp4
-rw-r--r--src/corelib/kernel/qsequentialiterable.cpp10
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp4
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp19
-rw-r--r--src/corelib/mimetypes/qmimeprovider_p.h2
-rw-r--r--src/corelib/platform/wasm/qstdweb.cpp265
-rw-r--r--src/corelib/platform/wasm/qstdweb_p.h77
-rw-r--r--src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp47
-rw-r--r--src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h2
-rw-r--r--src/corelib/plugin/qlibrary.h1
-rw-r--r--src/corelib/plugin/qlibrary_p.h7
-rw-r--r--src/corelib/serialization/qdatastream.cpp88
-rw-r--r--src/corelib/text/qbytearray.cpp79
-rw-r--r--src/corelib/text/qbytearray.h8
-rw-r--r--src/corelib/text/qlatin1stringview.h25
-rw-r--r--src/corelib/text/qlatin1stringview.qdoc6
-rw-r--r--src/corelib/text/qstring.cpp101
-rw-r--r--src/corelib/text/qstringiterator_p.h22
-rw-r--r--src/corelib/text/qunicodetables.cpp7197
-rw-r--r--src/corelib/text/qunicodetables_p.h5
-rw-r--r--src/corelib/text/qunicodetools.cpp129
-rw-r--r--src/corelib/thread/qatomic.cpp13
-rw-r--r--src/corelib/thread/qatomic.h1
-rw-r--r--src/corelib/thread/qbasicatomic.h1
-rw-r--r--src/corelib/thread/qthread.h28
-rw-r--r--src/corelib/time/qdatetime.cpp186
-rw-r--r--src/corelib/time/qdatetimeparser.cpp2
-rw-r--r--src/corelib/time/qgregoriancalendar.cpp1
-rw-r--r--src/corelib/time/qjalalicalendar.cpp1
-rw-r--r--src/corelib/time/qjuliancalendar.cpp1
-rw-r--r--src/corelib/time/qmilankoviccalendar.cpp1
-rw-r--r--src/corelib/time/qromancalendar.cpp1
-rw-r--r--src/corelib/time/qtimezone.cpp7
-rw-r--r--src/corelib/time/qtimezonelocale.cpp6
-rw-r--r--src/corelib/time/qtimezoneprivate.cpp2
-rw-r--r--src/corelib/time/qtimezoneprivate_p.h5
-rw-r--r--src/corelib/tools/qarraydata.h2
-rw-r--r--src/corelib/tools/qiterator.qdoc20
-rw-r--r--src/dbus/qt_attribution.json2
-rw-r--r--src/gui/accessible/linux/atspiadaptor.cpp15
-rw-r--r--src/gui/accessible/qaccessible.cpp78
-rw-r--r--src/gui/accessible/qaccessible_base.h3
-rw-r--r--src/gui/accessible/qaccessiblehelper.cpp77
-rw-r--r--src/gui/accessible/qaccessiblehelper_p.h18
-rw-r--r--src/gui/configure.cmake11
-rw-r--r--src/gui/doc/src/richtext.qdoc6
-rw-r--r--src/gui/image/qimage.cpp5
-rw-r--r--src/gui/image/qplatformpixmap.h7
-rw-r--r--src/gui/itemmodels/qfilesystemmodel.cpp9
-rw-r--r--src/gui/painting/qtextureglyphcache.cpp2
-rw-r--r--src/gui/rhi/qrhigles2.cpp2
-rw-r--r--src/gui/rhi/qrhigles2_p.h1
-rw-r--r--src/gui/text/qfont_p.h4
-rw-r--r--src/gui/text/qtextengine.cpp61
-rw-r--r--src/gui/text/qtextengine_p.h4
-rw-r--r--src/network/access/qhttpnetworkrequest.cpp15
-rw-r--r--src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm19
-rw-r--r--src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm2
-rw-r--r--src/plugins/platforms/ios/qiostheme.h1
-rw-r--r--src/plugins/platforms/ios/qiostheme.mm6
-rw-r--r--src/plugins/platforms/ios/quiwindow.mm2
-rw-r--r--src/plugins/platforms/wasm/qwasmaccessibility.cpp28
-rw-r--r--src/plugins/platforms/wasm/qwasmaccessibility.h1
-rw-r--r--src/plugins/platforms/wasm/qwasminputcontext.cpp65
-rw-r--r--src/plugins/platforms/wasm/qwasminputcontext.h2
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp13
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.h2
-rw-r--r--src/plugins/platforms/wayland/CMakeLists.txt8
-rw-r--r--src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp1
-rw-r--r--src/plugins/platforms/wayland/qwaylandinputdevice.cpp4
-rw-r--r--src/plugins/platforms/windows/qwindowsiconengine.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.cpp22
-rw-r--r--src/plugins/platforms/windows/qwindowsscreen.h2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp32
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h2
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp15
-rw-r--r--src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp1
-rw-r--r--src/plugins/platforms/xcb/CMakeLists.txt24
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp175
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qbackingstore_x11_p.h38
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qcolormap_x11.cpp615
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qcolormap_x11_p.h43
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp2807
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h86
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp2087
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h131
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qpolygonclipper_p.h278
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qt_x11_p.h163
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qtessellator.cpp1466
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qtessellator_p.h51
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp288
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.h64
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbimage.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp31
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h2
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style.cpp269
-rw-r--r--src/plugins/styles/modernwindows/qwindows11style_p.h9
-rw-r--r--src/plugins/styles/modernwindows/qwindowsvistastyle.cpp21
-rw-r--r--src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h2
-rw-r--r--src/testlib/qtestcase.h1
-rw-r--r--src/tools/bootstrap/CMakeLists.txt1
-rw-r--r--src/tools/windeployqt/main.cpp8
-rw-r--r--src/widgets/CMakeLists.txt1
-rw-r--r--src/widgets/accessible/itemviews.cpp4
-rw-r--r--src/widgets/accessible/itemviews_p.h4
-rw-r--r--src/widgets/accessible/qaccessiblewidgets.cpp46
-rw-r--r--src/widgets/accessible/rangecontrols.cpp26
-rw-r--r--src/widgets/accessible/rangecontrols_p.h5
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp256
-rw-r--r--src/widgets/dialogs/qcolorwell_p.h142
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp1
-rw-r--r--src/widgets/dialogs/qfiledialog.ui10
-rw-r--r--src/widgets/dialogs/qfiledialog_p.h5
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp2
-rw-r--r--src/widgets/styles/qcommonstyle.cpp21
-rw-r--r--src/widgets/styles/qwindowsstyle.cpp13
-rw-r--r--src/widgets/widgets/qlineedit_p.cpp7
-rw-r--r--src/widgets/widgets/qtabbar.cpp2
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/CMakeLists.txt6
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/RunCMakeTest.cmake63
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/check.cmake63
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGen.cmake67
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGenIntro.cmake12
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/full.cmake17
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/minimal.cmake11
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/subprojects/CMakeLists.txt5
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/CMakeLists.txt51
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/subproj1_helper.cpp4
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/CMakeLists.txt46
-rw-r--r--tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/subproj2_helper.cpp4
-rw-r--r--tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp13
-rw-r--r--tests/auto/corelib/global/qcheckedint/tst_qcheckedint.cpp2
-rw-r--r--tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp22
-rw-r--r--tests/auto/corelib/global/qglobal/tst_qglobal.cpp2
-rw-r--r--tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp2
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp2
-rw-r--r--tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp6
-rw-r--r--tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp39
-rw-r--r--tests/auto/corelib/itemmodels/CMakeLists.txt2
-rw-r--r--tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp2
-rw-r--r--tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp7
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp25
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h7
-rw-r--r--tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp10
-rw-r--r--tests/auto/corelib/kernel/qobject/tst_qobject.cpp3
-rw-r--r--tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp4
-rw-r--r--tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp27
-rw-r--r--tests/auto/corelib/plugin/CMakeLists.txt4
-rw-r--r--tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt2
-rw-r--r--tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp8
-rw-r--r--tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp7
-rw-r--r--tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp61
-rw-r--r--tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp12
-rw-r--r--tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp46
-rw-r--r--tests/auto/corelib/time/CMakeLists.txt4
-rw-r--r--tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp3
-rw-r--r--tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp32
-rw-r--r--tests/auto/corelib/tools/collections/tst_collections.cpp4
-rw-r--r--tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp6
-rw-r--r--tests/auto/gui/kernel/qwindow/tst_qwindow.cpp1
-rw-r--r--tests/auto/other/languagechange/tst_languagechange.cpp4
-rw-r--r--tests/auto/other/qaccessibility/tst_qaccessibility.cpp34
-rw-r--r--tests/auto/other/qfocusevent/tst_qfocusevent.cpp2
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp4
-rw-r--r--tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp1
-rw-r--r--tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp9
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp95
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp7
-rw-r--r--tests/manual/CMakeLists.txt1
-rw-r--r--tests/manual/assets/CMakeLists.txt4
-rw-r--r--tests/manual/assets/assets.pro3
-rw-r--r--tests/manual/assets/downloader/CMakeLists.txt15
-rw-r--r--tests/manual/assets/downloader/downloader.pro5
-rw-r--r--tests/manual/assets/downloader/main.cpp48
-rw-r--r--tests/manual/highdpi/pixelgadget/CMakeLists.txt6
-rw-r--r--tests/manual/highdpi/screengadget/CMakeLists.txt6
-rw-r--r--tests/manual/manual.pro1
-rw-r--r--tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp45
-rw-r--r--tests/manual/wasm/qtwasmtestlib/qtwasmtestlib.cpp2
-rw-r--r--util/sbom/cyclonedx/.gitignore6
-rw-r--r--util/sbom/cyclonedx/Makefile14
-rw-r--r--util/sbom/cyclonedx/README.md54
-rw-r--r--util/sbom/cyclonedx/pyproject.toml54
-rw-r--r--util/sbom/cyclonedx/qt_cyclonedx_generator/__init__.py2
-rw-r--r--util/sbom/cyclonedx/qt_cyclonedx_generator/qt_cyclonedx_generator.py881
-rw-r--r--util/sbom/cyclonedx/uv.lock625
-rw-r--r--util/unicode/main.cpp113
-rw-r--r--util/xkbdatagen/main.cpp4
330 files changed, 19497 insertions, 23222 deletions
diff --git a/.gitignore b/.gitignore
index 83c3424e9ae..20aff5f53d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -224,6 +224,7 @@ qtc-qmldbg/
callgrind.out.*
core
Makefile*
+!/util/sbom/cyclonedx/Makefile
!/qmake/Makefile.win32*
!/qmake/Makefile.unix
pcviewer.cfg
diff --git a/cmake/QtBuildHelpers.cmake b/cmake/QtBuildHelpers.cmake
index b6132ddae7e..7205bad5253 100644
--- a/cmake/QtBuildHelpers.cmake
+++ b/cmake/QtBuildHelpers.cmake
@@ -295,10 +295,13 @@ function(qt_internal_get_qt_build_public_helpers out_var)
QtPublicPluginHelpers
QtPublicPluginHelpers_v2
QtPublicSbomAttributionHelpers
+ QtPublicSbomCommonGenerationHelpers
QtPublicSbomCpeHelpers
+ QtPublicSbomCycloneDXHelpers
QtPublicSbomDepHelpers
QtPublicSbomFileHelpers
QtPublicSbomGenerationHelpers
+ QtPublicSbomGenerationCycloneDXHelpers
QtPublicSbomHelpers
QtPublicSbomLicenseHelpers
QtPublicSbomOpsHelpers
diff --git a/cmake/QtBuildInformation.cmake b/cmake/QtBuildInformation.cmake
index 77c6d8184b3..5c44a7e5f48 100644
--- a/cmake/QtBuildInformation.cmake
+++ b/cmake/QtBuildInformation.cmake
@@ -47,6 +47,11 @@ function(qt_print_feature_summary)
endforeach()
endif()
+ # Print an SBOM section for a top-level build, or a single repo.
+ if(NOT QT_NO_SBOM_SUMMARY_INFO)
+ qt_internal_add_sbom_summary_info()
+ endif()
+
# Show which packages were found.
feature_summary(INCLUDE_QUIET_PACKAGES
WHAT PACKAGES_FOUND
diff --git a/cmake/QtProcessConfigureArgs.cmake b/cmake/QtProcessConfigureArgs.cmake
index 7118f1f6f92..05e179ba3b3 100644
--- a/cmake/QtProcessConfigureArgs.cmake
+++ b/cmake/QtProcessConfigureArgs.cmake
@@ -351,12 +351,33 @@ endfunction()
macro(qt_add_common_commandline_options)
qt_commandline_option(headersclean TYPE boolean)
qt_commandline_option(sbom TYPE boolean CMAKE_VARIABLE QT_GENERATE_SBOM)
- qt_commandline_option(sbom-json TYPE boolean CMAKE_VARIABLE QT_SBOM_GENERATE_JSON)
+
+ # Semi-public, undocumented.
+ qt_commandline_option(sbom-all TYPE boolean CMAKE_VARIABLE QT_SBOM_GENERATE_AND_VERIFY_ALL)
+
+ qt_commandline_option(sbom-spdx-v2 TYPE boolean
+ CMAKE_VARIABLE QT_SBOM_GENERATE_SPDX_V2)
+
+ qt_commandline_option(sbom-cyclonedx-v1_6 TYPE boolean
+ CMAKE_VARIABLE QT_SBOM_GENERATE_CYDX_V1_6)
+
+ qt_commandline_option(sbom-cyclonedx-v1_6-required TYPE boolean
+ CMAKE_VARIABLE QT_SBOM_REQUIRE_GENERATE_CYDX_V1_6)
+
+ qt_commandline_option(sbom-cyclonedx-v1_6-verify-required TYPE boolean
+ CMAKE_VARIABLE QT_SBOM_REQUIRE_VERIFY_CYDX_V1_6)
+
+ qt_commandline_option(sbom-cyclonedx-v1_6-verbose TYPE boolean
+ CMAKE_VARIABLE QT_SBOM_VERBOSE_CYDX_V1_6)
+
+ qt_commandline_option(sbom-json TYPE boolean CMAKE_VARIABLE QT_SBOM_GENERATE_SPDX_V2_JSON)
qt_commandline_option(sbom-json-required TYPE boolean
- CMAKE_VARIABLE QT_SBOM_REQUIRE_GENERATE_JSON
+ CMAKE_VARIABLE QT_SBOM_REQUIRE_GENERATE_SPDX_V2_JSON
)
- qt_commandline_option(sbom-verify TYPE boolean CMAKE_VARIABLE QT_SBOM_VERIFY)
- qt_commandline_option(sbom-verify-required TYPE boolean CMAKE_VARIABLE QT_SBOM_REQUIRE_VERIFY)
+
+ qt_commandline_option(sbom-verify TYPE boolean CMAKE_VARIABLE QT_SBOM_VERIFY_SPDX_V2)
+ qt_commandline_option(sbom-verify-required TYPE boolean
+ CMAKE_VARIABLE QT_SBOM_REQUIRE_VERIFY_SPDX_V2)
endmacro()
function(qt_commandline_prefix arg var)
diff --git a/cmake/QtPublicSbomCommonGenerationHelpers.cmake b/cmake/QtPublicSbomCommonGenerationHelpers.cmake
new file mode 100644
index 00000000000..9de2055b5b6
--- /dev/null
+++ b/cmake/QtPublicSbomCommonGenerationHelpers.cmake
@@ -0,0 +1,668 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Helper function to get common project related variables for SBOM generation for both SPDX and
+# CycloneDX formats.
+function(_qt_internal_sbom_get_common_project_variables)
+ set(opt_args "")
+ set(single_args
+ # Forwarded
+ OUTPUT
+ OUTPUT_RELATIVE_PATH
+ COPYRIGHT
+ PROJECT
+ PROJECT_FOR_SPDX_ID
+ SUPPLIER
+ SUPPLIER_URL
+
+ # Custom inputs
+ DEFAULT_SBOM_FILE_NAME_EXTENSION
+
+ # Out vars
+ OUT_VAR_PROJECT_NAME
+ OUT_VAR_CURRENT_UTC
+ OUT_VAR_CURRENT_YEAR
+ OUT_VAR_OUTPUT
+ OUT_VAR_OUTPUT_RELATIVE_PATH
+ OUT_VAR_PROJECT_FOR_SPDX_ID
+ OUT_VAR_COPYRIGHT
+ OUT_VAR_SUPPLIER
+ OUT_VAR_SUPPLIER_URL
+ OUT_VAR_DEFAULT_PROJECT_COMMENT
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+
+ if(QT_SBOM_FAKE_TIMESTAMP)
+ set(current_utc "2590-01-01T11:33:55Z")
+ set(current_year "2590")
+ else()
+ string(TIMESTAMP current_utc UTC)
+ string(TIMESTAMP current_year "%Y" UTC)
+ endif()
+
+ set(${arg_OUT_VAR_CURRENT_UTC} "${current_utc}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_CURRENT_YEAR} "${current_year}" PARENT_SCOPE)
+
+ _qt_internal_sbom_set_default_option_value(PROJECT "${PROJECT_NAME}")
+ set(${arg_OUT_VAR_PROJECT_NAME} "${arg_PROJECT}" PARENT_SCOPE)
+
+ _qt_internal_sbom_get_git_version_vars()
+
+ _qt_internal_path_join(default_sbom_file_name
+ "${arg_PROJECT}"
+ "${arg_PROJECT}-sbom-${QT_SBOM_GIT_VERSION_PATH}.${arg_DEFAULT_SBOM_FILE_NAME_EXTENSION}")
+ _qt_internal_path_join(default_install_sbom_path
+ "\${CMAKE_INSTALL_PREFIX}/" "${CMAKE_INSTALL_DATAROOTDIR}" "${default_sbom_file_name}"
+ )
+
+ _qt_internal_sbom_set_default_option_value(OUTPUT "${default_install_sbom_path}")
+ _qt_internal_sbom_set_default_option_value(OUTPUT_RELATIVE_PATH
+ "${default_sbom_file_name}")
+
+ set(${arg_OUT_VAR_OUTPUT} "${arg_OUTPUT}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_OUTPUT_RELATIVE_PATH} "${arg_OUTPUT_RELATIVE_PATH}" PARENT_SCOPE)
+
+ _qt_internal_sbom_set_default_option_value(PROJECT_FOR_SPDX_ID "Package-${arg_PROJECT}")
+ string(REGEX REPLACE "[^A-Za-z0-9.]+" "-" arg_PROJECT_FOR_SPDX_ID "${arg_PROJECT_FOR_SPDX_ID}")
+ string(REGEX REPLACE "-+$" "" arg_PROJECT_FOR_SPDX_ID "${arg_PROJECT_FOR_SPDX_ID}")
+
+ # Prevent collision with other generated SPDXID with -[0-9]+ suffix.
+ string(REGEX REPLACE "-([0-9]+)$" "\\1" arg_PROJECT_FOR_SPDX_ID "${arg_PROJECT_FOR_SPDX_ID}")
+
+ set(project_spdx_id "SPDXRef-${arg_PROJECT_FOR_SPDX_ID}")
+ set(${arg_OUT_VAR_PROJECT_FOR_SPDX_ID} "${project_spdx_id}" PARENT_SCOPE)
+
+ _qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER "")
+ set(${arg_OUT_VAR_SUPPLIER} "${arg_SUPPLIER}" PARENT_SCOPE)
+
+ _qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER_URL
+ "${PROJECT_HOMEPAGE_URL}")
+ set(${arg_OUT_VAR_SUPPLIER_URL} "${arg_SUPPLIER_URL}" PARENT_SCOPE)
+
+ _qt_internal_sbom_set_default_option_value(COPYRIGHT "${current_year} ${arg_SUPPLIER}")
+ set(${arg_OUT_VAR_COPYRIGHT} "${arg_COPYRIGHT}" PARENT_SCOPE)
+
+ get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ set(cmake_configs "${CMAKE_CONFIGURATION_TYPES}")
+ else()
+ set(cmake_configs "${CMAKE_BUILD_TYPE}")
+ endif()
+
+ set(cmake_version "Built by CMake ${CMAKE_VERSION}")
+ set(system_name_and_processor "${CMAKE_SYSTEM_NAME} (${CMAKE_SYSTEM_PROCESSOR})")
+ set(default_project_comment
+ "${cmake_version} with ${cmake_configs} configuration for ${system_name_and_processor}")
+ set(${arg_OUT_VAR_DEFAULT_PROJECT_COMMENT} "${default_project_comment}" PARENT_SCOPE)
+endfunction()
+
+# Helper function to save SBOM project path values like relative build and install dirs,
+# in global properties.
+function(_qt_internal_sbom_save_common_path_variables_in_global_properties)
+ set(opt_args "")
+ set(single_args
+ OUTPUT
+ OUTPUT_RELATIVE_PATH
+ SBOM_DIR
+ PROPERTY_SUFFIX
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ get_filename_component(output_file_name_without_ext "${arg_OUTPUT}" NAME_WLE)
+ get_filename_component(output_file_ext "${arg_OUTPUT}" LAST_EXT)
+
+ set(computed_sbom_file_name_without_ext "${output_file_name_without_ext}${multi_config_suffix}")
+ set(computed_sbom_file_name "${output_file_name_without_ext}${output_file_ext}")
+
+ # In a super build and in a no-prefix build, put all the build time sboms into the same dir in,
+ # in the qtbase build dir.
+ if(QT_BUILDING_QT AND (QT_SUPERBUILD OR (NOT QT_WILL_INSTALL)))
+ set(build_sbom_root_dir "${QT_BUILD_DIR}")
+ else()
+ set(build_sbom_root_dir "${arg_SBOM_DIR}")
+ endif()
+
+ get_filename_component(output_relative_dir "${arg_OUTPUT_RELATIVE_PATH}" DIRECTORY)
+
+ set(build_sbom_dir "${build_sbom_root_dir}/${output_relative_dir}")
+ set(build_sbom_path "${build_sbom_dir}/${computed_sbom_file_name}")
+ set(build_sbom_path_without_ext
+ "${build_sbom_dir}/${computed_sbom_file_name_without_ext}")
+
+ set(install_sbom_path "${arg_OUTPUT}")
+
+ get_filename_component(install_sbom_dir "${install_sbom_path}" DIRECTORY)
+ set(install_sbom_path_without_ext "${install_sbom_dir}/${output_file_name_without_ext}")
+
+ set(suffix "${arg_PROPERTY_SUFFIX}")
+
+ set_property(GLOBAL PROPERTY _qt_sbom_build_output_path${suffix} "${build_sbom_path}")
+ set_property(GLOBAL PROPERTY _qt_sbom_build_output_path_without_ext${suffix}
+ "${build_sbom_path_without_ext}")
+ set_property(GLOBAL PROPERTY _qt_sbom_build_output_dir${suffix} "${build_sbom_dir}")
+
+ set_property(GLOBAL PROPERTY _qt_sbom_install_output_path${suffix} "${install_sbom_path}")
+ set_property(GLOBAL PROPERTY _qt_sbom_install_output_path_without_ext${suffix}
+ "${install_sbom_path_without_ext}")
+ set_property(GLOBAL PROPERTY _qt_sbom_install_output_dir${suffix} "${install_sbom_dir}")
+endfunction()
+
+# Helper function to get SBOM project path values like relative build and install dirs,
+function(_qt_internal_sbom_get_common_path_variables_from_global_properties)
+ set(opt_args "")
+ set(single_args
+ SBOM_FORMAT
+ OUT_VAR_SBOM_BUILD_OUTPUT_PATH
+ OUT_VAR_SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT
+ OUT_VAR_SBOM_BUILD_OUTPUT_DIR
+ OUT_VAR_SBOM_INSTALL_OUTPUT_PATH
+ OUT_VAR_SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT
+ OUT_VAR_SBOM_INSTALL_OUTPUT_DIR
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(arg_SBOM_FORMAT STREQUAL "SPDX_V2")
+ set(suffix "")
+ elseif(arg_SBOM_FORMAT STREQUAL "CYDX_V1_6")
+ set(suffix "_cydx")
+ endif()
+
+ get_property(sbom_build_output_path GLOBAL PROPERTY _qt_sbom_build_output_path${suffix})
+ get_property(sbom_build_output_path_without_ext GLOBAL PROPERTY
+ _qt_sbom_build_output_path_without_ext${suffix})
+ get_property(sbom_build_output_dir GLOBAL PROPERTY _qt_sbom_build_output_dir${suffix})
+
+ get_property(sbom_install_output_path GLOBAL PROPERTY _qt_sbom_install_output_path${suffix})
+ get_property(sbom_install_output_path_without_ext GLOBAL PROPERTY
+ _qt_sbom_install_output_path_without_ext${suffix})
+ get_property(sbom_install_output_dir GLOBAL PROPERTY _qt_sbom_install_output_dir${suffix})
+
+ if(arg_OUT_VAR_SBOM_BUILD_OUTPUT_PATH)
+ set(${arg_OUT_VAR_SBOM_BUILD_OUTPUT_PATH} "${sbom_build_output_path}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT)
+ set(${arg_OUT_VAR_SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT}
+ "${sbom_build_output_path_without_ext}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_SBOM_BUILD_OUTPUT_DIR)
+ set(${arg_OUT_VAR_SBOM_BUILD_OUTPUT_DIR} "${sbom_build_output_dir}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_SBOM_INSTALL_OUTPUT_PATH)
+ set(${arg_OUT_VAR_SBOM_INSTALL_OUTPUT_PATH} "${sbom_install_output_path}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT)
+ set(${arg_OUT_VAR_SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT}
+ "${sbom_install_output_path_without_ext}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_SBOM_INSTALL_OUTPUT_DIR)
+ set(${arg_OUT_VAR_SBOM_INSTALL_OUTPUT_DIR} "${sbom_install_output_dir}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Helper function to create a staging file for SBOM generation.
+# It is the file that will be incrementally assembled by having content appended to it.
+# Also creates the intro file that will add the assembled content for the SBOM project, aka for the
+# main SPDX package or root CycloneDX component.
+function(_qt_internal_sbom_create_sbom_staging_file)
+ set(opt_args "")
+ set(single_args
+ CONTENT
+ SBOM_FORMAT
+ REPO_PROJECT_NAME_LOWERCASE
+ OUT_VAR_CREATE_STAGING_FILE
+ OUT_VAR_SBOM_DIR
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ # Create the directory that will contain all sbom related files.
+ _qt_internal_get_current_project_sbom_dir(sbom_dir)
+ file(MAKE_DIRECTORY "${sbom_dir}")
+
+ if(arg_SBOM_FORMAT STREQUAL "SPDX_V2")
+ set(doc_base_name "SPDXRef-DOCUMENT")
+ set(doc_extension "spdx.in")
+ set(suffix "")
+ set(extra_content "
+ set(QT_SBOM_EXTERNAL_DOC_REFS \"\")
+")
+ _qt_internal_get_staging_area_spdx_file_path(staging_area_file)
+ set(starting_message "Starting SPDX SBOM generation in build dir: ${staging_area_file}")
+ elseif(arg_SBOM_FORMAT STREQUAL "CYDX_V1_6")
+ set(doc_base_name "cydx-document")
+ set(doc_extension "cdx.in.toml")
+ set(suffix "_cydx")
+ set(extra_content "")
+ _qt_internal_get_staging_area_cydx_file_path(staging_area_file)
+ set(starting_message
+ "Starting CycloneDX SBOM TOML file generation in build dir: ${staging_area_file}")
+ endif()
+
+ # Generate project document intro spdx file.
+ set(document_intro_file_name
+ "${sbom_dir}/${doc_base_name}-${arg_REPO_PROJECT_NAME_LOWERCASE}.${doc_extension}")
+ file(GENERATE OUTPUT "${document_intro_file_name}" CONTENT "${content}")
+
+ get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ set(multi_config_suffix "-$<CONFIG>")
+ else()
+ set(multi_config_suffix "")
+ endif()
+
+ # Create cmake file to append the document intro spdx to the staging file.
+ set(create_staging_file
+ "${sbom_dir}/append_document_to_staging${suffix}${multi_config_suffix}.cmake")
+
+ set(content "
+ cmake_minimum_required(VERSION 3.16)
+ message(STATUS \"${starting_message}\")
+ ${extra_content}
+ file(READ \"${document_intro_file_name}\" content)
+ # Override any previous file because we're starting from scratch.
+ file(WRITE \"${staging_area_file}\" \"\${content}\")
+")
+ file(GENERATE OUTPUT "${create_staging_file}" CONTENT "${content}")
+
+ set(${arg_OUT_VAR_CREATE_STAGING_FILE} "${create_staging_file}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_SBOM_DIR} "${sbom_dir}" PARENT_SCOPE)
+endfunction()
+
+# Helper function to save common project info like supplier, project name, spdx id in global
+# properties.
+function(_qt_internal_sbom_save_project_info_in_global_properties)
+ set(opt_args "")
+ set(single_args
+ SUPPLIER
+ SUPPLIER_URL
+ NAMESPACE
+ PROJECT
+ PROJECT_SPDX_ID
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ set_property(GLOBAL PROPERTY _qt_sbom_project_supplier "${arg_SUPPLIER}")
+ set_property(GLOBAL PROPERTY _qt_sbom_project_supplier_url "${arg_SUPPLIER_URL}")
+ set_property(GLOBAL PROPERTY _qt_sbom_project_namespace "${arg_NAMESPACE}")
+
+ set_property(GLOBAL PROPERTY _qt_sbom_project_name "${arg_PROJECT}")
+ set_property(GLOBAL PROPERTY _qt_sbom_project_spdx_id "${arg_PROJECT_SPDX_ID}")
+endfunction()
+
+# Helper function to get cmake include files for SBOM generation from global properties.
+function(_qt_internal_sbom_get_cmake_include_files)
+ set(opt_args "")
+ set(single_args
+ SBOM_FORMAT
+ OUT_VAR_INCLUDES
+ OUT_VAR_BEFORE_CHECKSUM_INCLUDES
+ OUT_VAR_AFTER_CHECKSUM_INCLUDES
+ OUT_VAR_POST_GENERATION_INCLUDES
+ OUT_VAR_VERIFY_INCLUDES
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(arg_SBOM_FORMAT STREQUAL "SPDX_V2")
+ set(suffix "")
+ elseif(arg_SBOM_FORMAT STREQUAL "CYDX_V1_6")
+ set(suffix "_cydx")
+ endif()
+
+ _qt_internal_sbom_collect_cmake_include_files(includes
+ JOIN_WITH_NEWLINES
+ PROPERTIES _qt_sbom_cmake_include_files${suffix} _qt_sbom_cmake_end_include_files${suffix}
+ )
+
+ # Before checksum includes are included after the verification codes have been collected
+ # and before their merged checksum(s) has been computed.
+ _qt_internal_sbom_collect_cmake_include_files(before_checksum_includes
+ JOIN_WITH_NEWLINES
+ PROPERTIES _qt_sbom_cmake_before_checksum_include_files${suffix}
+ )
+
+ # After checksum includes are included after the checksum has been computed and written to the
+ # QT_SBOM_VERIFICATION_CODE variable.
+ _qt_internal_sbom_collect_cmake_include_files(after_checksum_includes
+ JOIN_WITH_NEWLINES
+ PROPERTIES _qt_sbom_cmake_after_checksum_include_files${suffix}
+ )
+
+ # Post generation includes are included for both build and install time sboms, after
+ # sbom generation has finished.
+ _qt_internal_sbom_collect_cmake_include_files(post_generation_includes
+ JOIN_WITH_NEWLINES
+ PROPERTIES _qt_sbom_cmake_post_generation_include_files${suffix}
+ )
+
+ # Verification only makes sense on installation, where the checksums are present.
+ _qt_internal_sbom_collect_cmake_include_files(verify_includes
+ JOIN_WITH_NEWLINES
+ PROPERTIES _qt_sbom_cmake_verify_include_files${suffix}
+ )
+
+ if(arg_OUT_VAR_INCLUDES)
+ set(${arg_OUT_VAR_INCLUDES} "${includes}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_INCLUDES)
+ set(${arg_OUT_VAR_BEFORE_CHECKSUM_INCLUDES} "${before_checksum_includes}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_INCLUDES)
+ set(${arg_OUT_VAR_AFTER_CHECKSUM_INCLUDES} "${after_checksum_includes}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_INCLUDES)
+ set(${arg_OUT_VAR_POST_GENERATION_INCLUDES} "${post_generation_includes}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_INCLUDES)
+ set(${arg_OUT_VAR_VERIFY_INCLUDES} "${verify_includes}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# Clears cmake include files for the current project from the global properties.
+function(_qt_internal_sbom_clear_cmake_include_files)
+ set(opt_args "")
+ set(single_args
+ SBOM_FORMAT
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(arg_SBOM_FORMAT STREQUAL "SPDX_V2")
+ set(suffix "")
+ elseif(arg_SBOM_FORMAT STREQUAL "CYDX_V1_6")
+ set(suffix "_cydx")
+ endif()
+
+ # Clean up properties, so that they are empty for possible next repo in a top-level build.
+ set_property(GLOBAL PROPERTY _qt_sbom_cmake_include_files${suffix} "")
+ set_property(GLOBAL PROPERTY _qt_sbom_cmake_end_include_files${suffix} "")
+ set_property(GLOBAL PROPERTY _qt_sbom_cmake_before_checksum_include_files${suffix} "")
+ set_property(GLOBAL PROPERTY _qt_sbom_cmake_after_checksum_include_files${suffix} "")
+ set_property(GLOBAL PROPERTY _qt_sbom_cmake_post_generation_include_files${suffix} "")
+ set_property(GLOBAL PROPERTY _qt_sbom_cmake_verify_include_files${suffix} "")
+endfunction()
+
+# Creates cmake build targets to create build-time SBOMs (for testing purposes only, because they
+# lack checksums for installed files).
+# Also creates the assemble_sbom cmake file that is used by both build-time and install-time
+# sbom generation.
+function(_qt_internal_sbom_create_build_time_sbom_targets)
+ set(opt_args "")
+ set(single_args
+ SBOM_FORMAT
+ REPO_PROJECT_NAME_LOWERCASE
+ REAL_QT_REPO_PROJECT_NAME_LOWERCASE
+ SBOM_BUILD_OUTPUT_PATH
+ SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT
+ SBOM_BUILD_OUTPUT_DIR
+ INCLUDES
+ POST_GENERATION_INCLUDES
+ OUT_VAR_ASSEMBLE_SBOM_INCLUDE_PATH
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(arg_SBOM_FORMAT STREQUAL "SPDX_V2")
+ set(suffix "")
+ set(extra_content "
+ set(QT_SBOM_PACKAGES \"\")
+ set(QT_SBOM_PACKAGES_WITH_VERIFICATION_CODES \"\")
+")
+ _qt_internal_get_staging_area_spdx_file_path(staging_area_file)
+ set(final_message "Finalizing SPDX SBOM generation in build dir")
+ set(build_comment "SPDX document")
+ elseif(arg_SBOM_FORMAT STREQUAL "CYDX_V1_6")
+ set(suffix "_cydx")
+ set(extra_content "")
+ _qt_internal_get_staging_area_cydx_file_path(staging_area_file)
+ set(final_message "Finalizing Cyclone DX SBOM TOML generation in build dir")
+ set(build_comment "Cyclone DX document")
+ endif()
+
+ get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ set(multi_config_suffix "-$<CONFIG>")
+ else()
+ set(multi_config_suffix "")
+ endif()
+
+ _qt_internal_get_current_project_sbom_dir(sbom_dir)
+ set(content "
+ # QT_SBOM_BUILD_TIME be set to FALSE at install time, so don't override if it's set.
+ # This allows reusing the same cmake file for both build and install.
+ if(NOT DEFINED QT_SBOM_BUILD_TIME)
+ set(QT_SBOM_BUILD_TIME TRUE)
+ endif()
+ if(NOT QT_SBOM_OUTPUT_PATH)
+ set(QT_SBOM_OUTPUT_DIR \"${arg_SBOM_BUILD_OUTPUT_DIR}\")
+ set(QT_SBOM_OUTPUT_PATH \"${arg_SBOM_BUILD_OUTPUT_PATH}\")
+ set(QT_SBOM_OUTPUT_PATH_WITHOUT_EXT \"${arg_SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT}\")
+ file(MAKE_DIRECTORY \"${arg_SBOM_BUILD_OUTPUT_DIR}\")
+ endif()
+ ${extra_content}
+ ${arg_INCLUDES}
+ if(QT_SBOM_BUILD_TIME)
+ message(STATUS \"${final_message}: \${QT_SBOM_OUTPUT_PATH}\")
+ configure_file(\"${staging_area_file}\" \"\${QT_SBOM_OUTPUT_PATH}\")
+ ${arg_POST_GENERATION_INCLUDES}
+ endif()
+")
+ set(assemble_sbom "${sbom_dir}/assemble_sbom${suffix}${multi_config_suffix}.cmake")
+ file(GENERATE OUTPUT "${assemble_sbom}" CONTENT "${content}")
+
+ if(NOT TARGET sbom)
+ add_custom_target(sbom)
+ endif()
+
+ # Create a build target to create a build-time sbom (no verification codes or sha1s).
+ set(repo_sbom_target "sbom_${arg_REPO_PROJECT_NAME_LOWERCASE}${suffix}")
+ set(comment "")
+ string(APPEND comment "Assembling build time ${build_comment} without checksums for "
+ "${arg_REPO_PROJECT_NAME_LOWERCASE}. Just for testing.")
+ add_custom_target(${repo_sbom_target}
+ COMMAND "${CMAKE_COMMAND}" -P "${assemble_sbom}"
+ COMMENT "${comment}"
+ VERBATIM
+ USES_TERMINAL # To avoid running two configs of the command in parallel
+ )
+
+ get_cmake_property(qt_repo_deps _qt_repo_deps_${arg_REAL_QT_REPO_PROJECT_NAME_LOWERCASE})
+ if(qt_repo_deps)
+ foreach(repo_dep IN LISTS qt_repo_deps)
+ set(repo_dep_sbom "sbom_${repo_dep}${suffix}")
+ if(TARGET "${repo_dep_sbom}")
+ add_dependencies(${repo_sbom_target} ${repo_dep_sbom})
+ endif()
+ endforeach()
+ endif()
+
+ add_dependencies(sbom ${repo_sbom_target})
+
+ set(${arg_OUT_VAR_ASSEMBLE_SBOM_INCLUDE_PATH} "${assemble_sbom}" PARENT_SCOPE)
+endfunction()
+
+# Helper function to setup install markers for multi-config generators.
+# Makes sure to wait for all configurations to finish installation before actually generating
+# the SBOM and removing the markers.
+function(_qt_internal_sbom_setup_multi_config_install_markers)
+ set(opt_args "")
+ set(single_args
+ SBOM_DIR
+ SBOM_FORMAT
+ REPO_PROJECT_NAME_LOWERCASE
+ OUT_VAR_EXTRA_CODE_BEGIN
+ OUT_VAR_EXTRA_CODE_INNER_END
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ set(extra_code_begin "")
+ set(extra_code_inner_end "")
+
+ get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+ if(NOT is_multi_config)
+ set(${arg_OUT_VAR_EXTRA_CODE_BEGIN} "${extra_code_begin}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_EXTRA_CODE_INNER_END} "${extra_code_inner_end}" PARENT_SCOPE)
+ return()
+ endif()
+
+ if(arg_SBOM_FORMAT STREQUAL "SPDX_V2")
+ set(suffix "_spdx")
+ elseif(arg_SBOM_FORMAT STREQUAL "CYDX_V1_6")
+ set(suffix "_cydx")
+ endif()
+
+ set(configs ${CMAKE_CONFIGURATION_TYPES})
+
+ set(install_markers_dir "${arg_SBOM_DIR}")
+ set(install_marker_path "${install_markers_dir}/finished_install${suffix}-$<CONFIG>.cmake")
+
+ set(install_marker_code "
+ message(STATUS \"Writing install marker for config $<CONFIG>: ${install_marker_path} \")
+ file(WRITE \"${install_marker_path}\" \"\")
+")
+
+ install(CODE "${install_marker_code}" COMPONENT sbom)
+ if(QT_SUPERBUILD)
+ install(CODE "${install_marker_code}"
+ COMPONENT "sbom_${arg_REPO_PROJECT_NAME_LOWERCASE}${suffix}"
+ EXCLUDE_FROM_ALL)
+ endif()
+
+ set(install_markers "")
+ foreach(config IN LISTS configs)
+ set(marker_path "${install_markers_dir}/finished_install${suffix}-${config}.cmake")
+ list(APPEND install_markers "${marker_path}")
+ # Remove the markers on reconfiguration, just in case there are stale ones.
+ if(EXISTS "${marker_path}")
+ file(REMOVE "${marker_path}")
+ endif()
+ endforeach()
+
+ # Escape the semicolons in install_makers, so they don't break argument parsing in
+ # _qt_internal_sbom_setup_sbom_install_code when they are forwarded there.
+ string(REPLACE ";" "\\;" install_markers "${install_markers}")
+
+ set(extra_code_begin "
+ set(QT_SBOM_INSTALL_MARKERS${suffix} \"${install_markers}\")
+ foreach(QT_SBOM_INSTALL_MARKER IN LISTS QT_SBOM_INSTALL_MARKERS${suffix})
+ if(NOT EXISTS \"\${QT_SBOM_INSTALL_MARKER}\")
+ set(QT_SBOM_INSTALLED_ALL_CONFIGS${suffix} FALSE)
+ endif()
+ endforeach()
+")
+ set(extra_code_inner_end "
+ foreach(QT_SBOM_INSTALL_MARKER IN LISTS QT_SBOM_INSTALL_MARKERS${suffix})
+ message(STATUS
+ \"Removing install marker: \${QT_SBOM_INSTALL_MARKER} \")
+ file(REMOVE \"\${QT_SBOM_INSTALL_MARKER}\")
+ endforeach()
+")
+
+ set(${arg_OUT_VAR_EXTRA_CODE_BEGIN} "${extra_code_begin}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_EXTRA_CODE_INNER_END} "${extra_code_inner_end}" PARENT_SCOPE)
+endfunction()
+
+# Helper function to setup the fake checksum code snippet.
+function(_qt_internal_sbom_setup_fake_checksum)
+ set(opt_args "")
+ set(single_args
+ OUT_VAR_FAKE_CHECKSUM_CODE
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ # Allow skipping checksum computation for testing purposes, while installing just the sbom
+ # documents, without requiring to build and install all the actual files.
+ set(extra_code "")
+ if(QT_SBOM_FAKE_CHECKSUM)
+ string(APPEND extra_code "
+ set(QT_SBOM_FAKE_CHECKSUM TRUE)")
+ endif()
+
+ set(${arg_OUT_VAR_FAKE_CHECKSUM_CODE} "${extra_code}" PARENT_SCOPE)
+endfunction()
+
+# Helper function to setup the install-time SBOM generation code.
+function(_qt_internal_sbom_setup_sbom_install_code)
+ set(opt_args "")
+ set(single_args
+ SBOM_FORMAT
+ REPO_PROJECT_NAME_LOWERCASE
+
+ SBOM_INSTALL_OUTPUT_PATH
+ SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT
+ SBOM_INSTALL_OUTPUT_DIR
+
+ ASSEMBLE_SBOM_INCLUDE_PATH
+
+ EXTRA_CODE_BEGIN
+ EXTRA_CODE_INNER_END
+ PROCESS_VERIFICATION_CODES
+
+ BEFORE_CHECKSUM_INCLUDES
+ AFTER_CHECKSUM_INCLUDES
+ POST_GENERATION_INCLUDES
+ VERIFY_INCLUDES
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(arg_SBOM_FORMAT STREQUAL "SPDX_V2")
+ set(suffix "_spdx")
+ _qt_internal_get_staging_area_spdx_file_path(staging_area_file)
+ set(final_message "Finalizing SBOM generation in install dir")
+ set(process_verification_codes "
+ include(\"${arg_PROCESS_VERIFICATION_CODES}\")
+")
+ elseif(arg_SBOM_FORMAT STREQUAL "CYDX_V1_6")
+ set(suffix "_cydx")
+ set(final_message "Finalizing intermediate TOML generation in install dir")
+
+ set(process_verification_codes "")
+ _qt_internal_get_staging_area_cydx_file_path(staging_area_file)
+ endif()
+
+ set(assemble_sbom_install "
+ set(QT_SBOM_INSTALLED_ALL_CONFIGS${suffix} TRUE)
+ ${arg_EXTRA_CODE_BEGIN}
+ if(QT_SBOM_INSTALLED_ALL_CONFIGS${suffix})
+ set(QT_SBOM_BUILD_TIME FALSE)
+ set(QT_SBOM_OUTPUT_DIR \"${arg_SBOM_INSTALL_OUTPUT_DIR}\")
+ set(QT_SBOM_OUTPUT_PATH \"${arg_SBOM_INSTALL_OUTPUT_PATH}\")
+ set(QT_SBOM_OUTPUT_PATH_WITHOUT_EXT \"${arg_SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT}\")
+ file(MAKE_DIRECTORY \"${arg_SBOM_INSTALL_OUTPUT_DIR}\")
+ include(\"${arg_ASSEMBLE_SBOM_INCLUDE_PATH}\")
+ ${arg_BEFORE_CHECKSUM_INCLUDES}
+ ${process_verification_codes}
+ ${arg_AFTER_CHECKSUM_INCLUDES}
+ message(STATUS \"${final_message}: \${QT_SBOM_OUTPUT_PATH}\")
+ configure_file(\"${staging_area_file}\" \"\${QT_SBOM_OUTPUT_PATH}\")
+ ${arg_POST_GENERATION_INCLUDES}
+ ${arg_VERIFY_INCLUDES}
+ ${arg_EXTRA_CODE_INNER_END}
+ else()
+ message(STATUS \"Skipping SBOM finalization because not all configs were installed.\")
+ endif()
+")
+
+ install(CODE "${assemble_sbom_install}" COMPONENT sbom)
+ if(QT_SUPERBUILD)
+ install(CODE "${assemble_sbom_install}" COMPONENT "sbom_${arg_REPO_PROJECT_NAME_LOWERCASE}"
+ EXCLUDE_FROM_ALL)
+ endif()
+endfunction()
diff --git a/cmake/QtPublicSbomCycloneDXHelpers.cmake b/cmake/QtPublicSbomCycloneDXHelpers.cmake
new file mode 100644
index 00000000000..a3dc52d4e39
--- /dev/null
+++ b/cmake/QtPublicSbomCycloneDXHelpers.cmake
@@ -0,0 +1,382 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Gets the helper python script name and relative dir in the source dir.
+function(_qt_internal_sbom_get_cyclone_dx_generator_script_name
+ out_var_generator_name
+ out_var_generator_relative_dir)
+ set(generator_name "qt_cyclonedx_generator.py")
+
+ _qt_internal_path_join(generator_relative_dir
+ "util" "sbom" "cyclonedx" "qt_cyclonedx_generator")
+
+ set(${out_var_generator_name} "${generator_name}" PARENT_SCOPE)
+ set(${out_var_generator_relative_dir} "${generator_relative_dir}" PARENT_SCOPE)
+endfunction()
+
+# Ges the path to the helper python script, which should be used to generate CycloneDX document.
+# Prefers the source path over the installed path, for easier development of the script.
+function(_qt_internal_sbom_get_cyclone_dx_generator_path out_var)
+ _qt_internal_sbom_get_cyclone_dx_generator_script_name(generator_name generator_relative_dir)
+
+ _qt_internal_path_join(qtbase_script_path
+ "${QT_SOURCE_TREE}" "${generator_relative_dir}" "${generator_name}")
+ _qt_internal_path_join(installed_script_path
+ "${QT6_INSTALL_PREFIX}" "${QT6_INSTALL_LIBEXECS}" "${generator_name}")
+
+ # qtbase sources available, always use them, regardless if it's a prefix or non-prefix build.
+ # Makes development easier.
+ if(EXISTS "${qtbase_script_path}")
+ set(script_path "${qtbase_script_path}")
+
+ # qtbase sources unavailable, use installed files.
+ elseif(EXISTS "${installed_script_path}")
+ set(script_path "${installed_script_path}")
+ else()
+ message(FATAL_ERROR "Can't find ${generator_name} file.")
+ endif()
+
+ set(${out_var} "${script_path}" PARENT_SCOPE)
+endfunction()
+
+# Parses the options for a single CYDX_PROPERTY_ENTRY, and creates a toml snippet to add a
+# CycloneDX property to the final toml document.
+function(_qt_internal_sbom_parse_cydx_property_entry_options)
+ set(opt_args "")
+ set(single_args
+ CYDX_PROPERTY_NAME
+ CYDX_PROPERTY_VALUE
+ OUT_VAR
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_CYDX_PROPERTY_NAME)
+ message(FATAL_ERROR "CYDX_PROPERTY_NAME is required.")
+ endif()
+
+ if(NOT arg_CYDX_PROPERTY_VALUE)
+ message(FATAL_ERROR "CYDX_PROPERTY_VALUE is required.")
+ endif()
+
+ if(NOT arg_OUT_VAR)
+ message(FATAL_ERROR "OUT_VAR is required.")
+ endif()
+
+ set(${arg_OUT_VAR} "
+[[components.properties]]
+name = \\\"${arg_CYDX_PROPERTY_NAME}\\\"
+value = \\\"${arg_CYDX_PROPERTY_VALUE}\\\"
+" PARENT_SCOPE)
+endfunction()
+
+# Processes a list of CycloneDX property entries, and creates their toml representation as output.
+function(_qt_internal_sbom_handle_cydx_properties)
+ set(opt_args "")
+ set(single_args
+ OUT_VAR_CYDX_PROPERTIES_STRING
+ )
+ set(multi_args
+ CYDX_PROPERTIES
+ )
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_OUT_VAR_CYDX_PROPERTIES_STRING)
+ message(FATAL_ERROR "OUT_VAR_CYDX_PROPERTIES_STRING is required.")
+ endif()
+
+ # Collect each CYDX_PROPERTY_ENTRY args into a separate variable.
+ set(prop_idx -1)
+ set(prop_entry_indices "")
+
+ foreach(prop_arg IN LISTS arg_CYDX_PROPERTIES)
+ if(prop_arg STREQUAL "CYDX_PROPERTY_ENTRY")
+ math(EXPR prop_idx "${prop_idx}+1")
+ list(APPEND prop_entry_indices "${prop_idx}")
+ elseif(prop_idx GREATER_EQUAL 0)
+ list(APPEND prop_${prop_idx}_args "${prop_arg}")
+ else()
+ message(FATAL_ERROR "Missing CYDX_PROPERTY_ENTRY keyword.")
+ endif()
+ endforeach()
+
+ set(properties_string "")
+
+ foreach(prop_idx IN LISTS prop_entry_indices)
+ _qt_internal_sbom_parse_cydx_property_entry_options(
+ ${prop_${prop_idx}_args}
+ OUT_VAR property_tuple
+ )
+
+ string(APPEND properties_string "${property_tuple}")
+ endforeach()
+
+ set(${arg_OUT_VAR_CYDX_PROPERTIES_STRING} "${properties_string}" PARENT_SCOPE)
+endfunction()
+
+# Outputs extra Cyclone DX properties based on the sbom entity type.
+function(_qt_internal_sbom_handle_qt_entity_cydx_properties)
+ set(opt_args "")
+ set(single_args
+ SBOM_ENTITY_TYPE
+ OUT_CYDX_PROPERTIES
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_SBOM_ENTITY_TYPE)
+ message(FATAL_ERROR "SBOM_ENTITY_TYPE is required.")
+ endif()
+
+ if(NOT arg_OUT_CYDX_PROPERTIES)
+ message(FATAL_ERROR "OUT_CYDX_PROPERTIES is required.")
+ endif()
+
+ set(cydx_properties "")
+ list(APPEND cydx_properties
+ CYDX_PROPERTY_ENTRY
+ CYDX_PROPERTY_NAME "qt:sbom:entity_type"
+ CYDX_PROPERTY_VALUE "${arg_SBOM_ENTITY_TYPE}"
+ )
+
+ _qt_internal_sbom_is_qt_entity_type("${arg_SBOM_ENTITY_TYPE}" is_qt_entity_type)
+ if(is_qt_entity_type)
+ list(APPEND cydx_properties
+ CYDX_PROPERTY_ENTRY
+ CYDX_PROPERTY_NAME "qt:sbom:is_qt_entity_type"
+ CYDX_PROPERTY_VALUE "true"
+ )
+ endif()
+ _qt_internal_sbom_is_qt_3rd_party_entity_type("${arg_SBOM_ENTITY_TYPE}"
+ is_qt_3rd_party_entity_type)
+ if(is_qt_3rd_party_entity_type)
+ list(APPEND cydx_properties
+ CYDX_PROPERTY_ENTRY
+ CYDX_PROPERTY_NAME "qt:sbom:is_qt_3rd_party_entity_type"
+ CYDX_PROPERTY_VALUE "true"
+ )
+ endif()
+
+ set(${arg_OUT_CYDX_PROPERTIES} "${cydx_properties}" PARENT_SCOPE)
+endfunction()
+
+# Maps an sbom entity type to a cyclone dx component type.
+function(_qt_internal_sbom_get_cyclone_component_type out_var sbom_entity_type)
+ set(library_types
+ "QT_MODULE"
+ "QT_PLUGIN"
+ "QML_PLUGIN"
+ "QT_THIRD_PARTY_MODULE"
+ "QT_THIRD_PARTY_SOURCES"
+ "SYSTEM_LIBRARY"
+ "LIBRARY"
+ "THIRD_PARTY_LIBRARY"
+ "THIRD_PARTY_LIBRARY_WITH_FILES"
+ "THIRD_PARTY_SOURCES"
+ )
+
+ set(application_types
+ "QT_TOOL"
+ "QT_APP"
+ "EXECUTABLE"
+ )
+
+ if(sbom_entity_type IN_LIST library_types)
+ set(component_type "library")
+ elseif(sbom_entity_type IN_LIST application_types)
+ set(component_type "application")
+ else()
+ # Default to library for now, because it's unclear what would be a better default.
+ set(component_type "library")
+ endif()
+
+ set(${out_var} "${component_type}" PARENT_SCOPE)
+endfunction()
+
+# Generates a pseudo-unique serial number for a CycloneDX sbom document.
+#
+# The spec says that a BOM serial number must conform to RFC 4122, but doesn't specify which
+# kind of uuid version should be generated.
+# The upstream python library generates a version 4 uuid, which is fully random.
+# CMake can only generate version 3 and 5 uuids, which are fully deterministic based on the given
+# NAMESPACE and NAME values.
+# Generating a fully random uuid prevents build reproducibility. The maintainer of the Cyclone DX
+# spec even mentions that here:
+# https://github.com/CycloneDX/specification/issues/97#issuecomment-955904904
+# And yet to to do component-wise inter-document linking using the BOM-Link mechanism, you have to
+# use serial numbers.
+#
+# Because the spec doesn't explicitly prohibit it, we will generate a version 5 uuid based on the
+# SPDX_NAMESPACE passed to the function, which is supposed to be unique enough, because it contains
+# the project / document name (e.g. qtbase) and its version or git version.
+# This should alleviate the reproducibility problem as well.
+function(_qt_internal_sbom_get_cyclone_bom_serial_number)
+ set(opt_args "")
+ set(single_args
+ SPDX_NAMESPACE
+ OUT_VAR_UUID
+ OUT_VAR_SERIAL_NUMBER
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ _qt_internal_sbom_set_default_option_value_and_error_if_empty(SPDX_NAMESPACE "")
+
+ # This is a randomly generated uuid v4 value. To be used for all eternity. Until we change the
+ # implementation of the function.
+ set(uuid_namespace "c024642f-9853-45b2-9bfd-ab3f061a05bb")
+
+ string(UUID uuid NAMESPACE "${uuid_namespace}" NAME "${arg_SPDX_NAMESPACE}" TYPE SHA1)
+ set(cyclone_dx_serial_number "urn:cdx:${uuid}")
+
+ if(arg_OUT_VAR_UUID)
+ set("${arg_OUT_VAR_UUID}" "${uuid}" PARENT_SCOPE)
+ endif()
+ if(arg_OUT_VAR_SERIAL_NUMBER)
+ set("${arg_OUT_VAR_SERIAL_NUMBER}" "${cyclone_dx_serial_number}" PARENT_SCOPE)
+ endif()
+endfunction()
+
+# See https://github.com/CycloneDX/guides/blob/main/SBOM/en/0x52-Linking.md
+function(_qt_internal_sbom_get_cydx_external_bom_link target out_var)
+ get_target_property(spdx_id "${target}" _qt_sbom_spdx_id)
+ get_target_property(bom_serial_number "${target}" _qt_sbom_cydx_bom_serial_number_uuid)
+
+ set(bom_version "1")
+ set(bom_link "urn:cdx:${bom_serial_number}/${bom_version}#${spdx_id}")
+
+ set(${out_var} "${bom_link}" PARENT_SCOPE)
+endfunction()
+
+# Records necessary details of external target dependencies in global properties, to later create
+# the CycloneDX packages for them. The info collection needs to be done immediately in the directory
+# scope where the targets were found, because they might not be global, and thus can't be accessed
+# later.
+function(_qt_internal_sbom_record_external_target_dependecies)
+ set(opt_args "")
+ set(single_args "")
+ set(multi_args
+ TARGETS
+ )
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_TARGETS)
+ return()
+ endif()
+
+ get_property(existing_ids GLOBAL PROPERTY _qt_internal_sbom_external_target_dep_ids)
+ if(NOT existing_ids)
+ set(existing_ids "")
+ endif()
+
+ foreach(target IN LISTS arg_TARGETS)
+ # Use the full spdx id (one prefixed with the containing DocumentRef-) because that's what
+ # our spdx dependency relationships use at the moment.
+ # Both Foo and FooPrivate map to the same spdx_id, so we need to avoid duplicates on spdx id
+ # level.
+ get_target_property(spdx_id "${target}" _qt_sbom_spdx_id)
+
+ if(spdx_id IN_LIST existing_ids)
+ continue()
+ endif()
+
+ list(APPEND existing_ids "${spdx_id}")
+ set_property(GLOBAL APPEND PROPERTY _qt_internal_sbom_external_target_dep_ids "${spdx_id}")
+
+ # This is checked in _qt_internal_sbom_add_target, to prevent duplicate creation of
+ # system library targets.
+ set_property(GLOBAL APPEND PROPERTY _qt_internal_sbom_external_target_dependencies
+ "${target}")
+
+ get_target_property(package_name "${target}" _qt_sbom_package_name)
+ get_target_property(sbom_entity_type "${target}" _qt_sbom_entity_type)
+ get_target_property(package_version "${target}" _qt_sbom_package_version)
+ _qt_internal_sbom_get_cydx_external_bom_link("${target}" external_bom_link)
+
+ set_property(GLOBAL
+ PROPERTY "_qt_internal_sbom_external_target_dep_${spdx_id}_target"
+ "${target}")
+ set_property(GLOBAL
+ PROPERTY "_qt_internal_sbom_external_target_dep_${spdx_id}_package_name"
+ "${package_name}")
+ set_property(GLOBAL
+ PROPERTY "_qt_internal_sbom_external_target_dep_${spdx_id}_sbom_entity_type"
+ "${sbom_entity_type}")
+ set_property(GLOBAL
+ PROPERTY "_qt_internal_sbom_external_target_dep_${spdx_id}_package_version"
+ "${package_version}")
+ set_property(GLOBAL
+ PROPERTY "_qt_internal_sbom_external_target_dep_${spdx_id}_external_bom_link"
+ "${external_bom_link}")
+ endforeach()
+endfunction()
+
+# Goes through the list of recorded external target dependencies collected during target
+# dependency analysis, and adds them as CycloneDX packages to the CycloneDX document.
+# This is different from SPDX v2.3, which doesn't require creating a package for dependencies that
+# are defined in a different document.
+function(_qt_internal_sbom_add_cydx_external_target_dependencies)
+ get_property(spdx_ids GLOBAL PROPERTY _qt_internal_sbom_external_target_dep_ids)
+ if(NOT spdx_ids)
+ # Clean up external target dependencies, before configuring next repo project.
+ set_property(GLOBAL PROPERTY _qt_internal_sbom_external_target_dep_ids "")
+ set_property(GLOBAL PROPERTY _qt_internal_sbom_external_target_dependencies "")
+ return()
+ endif()
+
+ # Just in case, don't add duplicates.
+ set(visited_spdx_ids "")
+
+ foreach(spdx_id IN LISTS spdx_ids)
+ if(spdx_id IN_LIST visited_spdx_ids)
+ continue()
+ endif()
+
+ get_cmake_property(package_name
+ "_qt_internal_sbom_external_target_dep_${spdx_id}_package_name")
+ get_cmake_property(sbom_entity_type
+ "_qt_internal_sbom_external_target_dep_${spdx_id}_sbom_entity_type")
+ get_cmake_property(package_version
+ "_qt_internal_sbom_external_target_dep_${spdx_id}_package_version")
+ get_cmake_property(external_bom_link
+ "_qt_internal_sbom_external_target_dep_${spdx_id}_external_bom_link")
+
+ _qt_internal_sbom_generate_cyclone_add_package(
+ PACKAGE "${package_name}"
+ SPDXID "${spdx_id}"
+ SBOM_ENTITY_TYPE "${sbom_entity_type}"
+ VERSION "${package_version}"
+ EXTERNAL_BOM_LINK "${external_bom_link}"
+ )
+
+ list(APPEND visited_spdx_ids "${spdx_id}")
+ endforeach()
+
+ # Clean up external target dependencies, before configuring next repo project.
+ set_property(GLOBAL PROPERTY _qt_internal_sbom_external_target_dep_ids "")
+ set_property(GLOBAL PROPERTY _qt_internal_sbom_external_target_dependencies "")
+endfunction()
+
+# Records a license id and its text in global properties, to be added to the CycloneDX document
+# later.
+function(_qt_internal_sbom_record_license_cydx)
+ set(opt_args "")
+ set(single_args
+ LICENSE_ID
+ EXTRACTED_TEXT
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ set_property(GLOBAL APPEND PROPERTY
+ _qt_internal_sbom_cydx_licenses "${arg_LICENSE_ID}")
+ set_property(GLOBAL PROPERTY
+ _qt_internal_sbom_cydx_licenses_${arg_LICENSE_ID}_text "${arg_EXTRACTED_TEXT}"
+ )
+endfunction()
diff --git a/cmake/QtPublicSbomDepHelpers.cmake b/cmake/QtPublicSbomDepHelpers.cmake
index 32e3b6b832c..794f3f77db2 100644
--- a/cmake/QtPublicSbomDepHelpers.cmake
+++ b/cmake/QtPublicSbomDepHelpers.cmake
@@ -4,11 +4,17 @@
# Walks a target's direct dependencies and assembles a list of relationships between the packages
# of the target dependencies.
# Currently handles various Qt targets and system libraries.
+# For SPDX documents, it collects the relationships in OUT_SPDX_RELATIONSHIPS.
+# For CYDX documents, it collects the dependencies (not relationship info) in OUT_CYDX_DEPENDENCIES.
+# If a CYDX dependency is in an external docuemnt, the dependency is added to
+# OUT_EXTERNAL_TARGET_DEPENDENCIES instead.
function(_qt_internal_sbom_handle_target_dependencies target)
set(opt_args "")
set(single_args
SPDX_ID
- OUT_RELATIONSHIPS
+ OUT_CYDX_DEPENDENCIES
+ OUT_SPDX_RELATIONSHIPS
+ OUT_EXTERNAL_TARGET_DEPENDENCIES
)
set(multi_args
LIBRARIES
@@ -75,8 +81,12 @@ function(_qt_internal_sbom_handle_target_dependencies target)
set(all_direct_libraries ${libraries} ${public_libraries} ${sbom_dependencies})
list(REMOVE_DUPLICATES all_direct_libraries)
- set(spdx_dependencies "")
+ set(regular_cydx_dependencies "")
+ set(regular_spdx_dependencies "")
+
+ set(external_cydx_dependencies "")
set(external_spdx_dependencies "")
+ set(external_target_dependencies "")
# Go through each direct linked lib.
foreach(direct_lib IN LISTS all_direct_libraries)
@@ -108,7 +118,8 @@ function(_qt_internal_sbom_handle_target_dependencies target)
# Add a dependency on the vendored lib instead of the Wrap target.
if(is_3rdparty_bundled_lib AND lib_spdx_id)
- list(APPEND spdx_dependencies "${lib_spdx_id}")
+ list(APPEND regular_cydx_dependencies "${lib_spdx_id}")
+ list(APPEND regular_spdx_dependencies "${lib_spdx_id}")
set(bundled_targets_found TRUE)
endif()
endforeach()
@@ -148,30 +159,38 @@ function(_qt_internal_sbom_handle_target_dependencies target)
if(NOT is_dependency_in_external_document)
# If the target is not in the external document, it must be one built as part of the
# current project.
- list(APPEND spdx_dependencies "${lib_spdx_id}")
+ list(APPEND regular_cydx_dependencies "${lib_spdx_id}")
+ list(APPEND regular_spdx_dependencies "${lib_spdx_id}")
else()
# Refer to the package in the external document. This can be the case
# in a top-level build, where a system library is reused across repos, or for any
# regular dependency that was built as part of a different project.
_qt_internal_sbom_add_external_target_dependency("${direct_lib}"
- extra_spdx_dependencies
+ OUT_CYDX_DEPENDENCIES extra_cydx_dependencies
+ OUT_SPDX_DEPENDENCIES extra_spdx_dependencies
+ OUT_TARGET_DEPENDENCIES extra_target_dependencies
)
if(extra_spdx_dependencies)
+ list(APPEND external_cydx_dependencies ${extra_cydx_dependencies})
list(APPEND external_spdx_dependencies ${extra_spdx_dependencies})
+ list(APPEND external_target_dependencies ${extra_target_dependencies})
endif()
endif()
endforeach()
- set(relationships "")
+ set(spdx_relationships "")
+
# Keep the external dependencies first, so they are neatly ordered.
- foreach(dep_spdx_id IN LISTS external_spdx_dependencies spdx_dependencies)
- set(relationship
- "${package_spdx_id} DEPENDS_ON ${dep_spdx_id}"
- )
- list(APPEND relationships "${relationship}")
+ foreach(dep_spdx_id IN LISTS external_spdx_dependencies regular_spdx_dependencies)
+ set(relationship "${package_spdx_id} DEPENDS_ON ${dep_spdx_id}")
+ list(APPEND spdx_relationships "${relationship}")
endforeach()
- set(${arg_OUT_RELATIONSHIPS} "${relationships}" PARENT_SCOPE)
+ set(all_cydx_dependencies ${external_cydx_dependencies} ${regular_cydx_dependencies})
+
+ set(${arg_OUT_CYDX_DEPENDENCIES} "${all_cydx_dependencies}" PARENT_SCOPE)
+ set(${arg_OUT_SPDX_RELATIONSHIPS} "${spdx_relationships}" PARENT_SCOPE)
+ set(${arg_OUT_EXTERNAL_TARGET_DEPENDENCIES} "${external_target_dependencies}" PARENT_SCOPE)
endfunction()
# Checks whether the current target will have its sbom generated into the current repo sbom
@@ -205,18 +224,34 @@ function(_qt_internal_sbom_is_external_target_dependency target)
endfunction()
# Handles generating an external document reference SDPX element for each target package that is
-# located in a different spdx document.
-function(_qt_internal_sbom_add_external_target_dependency target out_spdx_dependencies)
+# located in a different spdx document, and collects the reference in OUT_SPDX_DEPENDENCIES.
+# In case of CycloneDX, we just collect the dependency spdx id (bom-ref) and the target name,
+# which are added to OUT_CYDX_DEPENDENCIES and OUT_TARGET_DEPENDENCIES respectively.
+function(_qt_internal_sbom_add_external_target_dependency target)
+ set(opt_args "")
+ set(single_args
+ OUT_CYDX_DEPENDENCIES
+ OUT_SPDX_DEPENDENCIES
+ OUT_TARGET_DEPENDENCIES
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
_qt_internal_sbom_get_spdx_id_for_target("${target}" dep_spdx_id)
if(NOT dep_spdx_id)
message(DEBUG "Could not add external target dependency on ${target} "
"because no spdx id could be found")
- set(${out_spdx_dependencies} "" PARENT_SCOPE)
+ set(${arg_OUT_CYDX_DEPENDENCIES} "" PARENT_SCOPE)
+ set(${arg_OUT_SPDX_DEPENDENCIES} "" PARENT_SCOPE)
+ set(${arg_OUT_TARGET_DEPENDENCIES} "" PARENT_SCOPE)
return()
endif()
+ set(cydx_dependencies "")
set(spdx_dependencies "")
+ set(target_depdendencies "")
# Get the external document path and the repo it belongs to for the given target.
get_property(relative_installed_repo_document_path TARGET ${target}
@@ -232,9 +267,11 @@ function(_qt_internal_sbom_add_external_target_dependency target out_spdx_depend
get_cmake_property(known_external_document
_qt_known_external_documents_${external_document_ref})
- set(dependency "${external_document_ref}:${dep_spdx_id}")
+ set(spdx_dependency "${external_document_ref}:${dep_spdx_id}")
- list(APPEND spdx_dependencies "${dependency}")
+ list(APPEND cydx_dependencies "${dep_spdx_id}")
+ list(APPEND spdx_dependencies "${spdx_dependency}")
+ list(APPEND target_depdendencies "${target}")
# Only add a reference to the external document package, if we haven't done so already.
if(NOT known_external_document)
@@ -261,5 +298,7 @@ function(_qt_internal_sbom_add_external_target_dependency target out_spdx_depend
"Missing spdx document path for external target dependency: ${target}")
endif()
- set(${out_spdx_dependencies} "${spdx_dependencies}" PARENT_SCOPE)
+ set(${arg_OUT_CYDX_DEPENDENCIES} "${cydx_dependencies}" PARENT_SCOPE)
+ set(${arg_OUT_SPDX_DEPENDENCIES} "${spdx_dependencies}" PARENT_SCOPE)
+ set(${arg_OUT_TARGET_DEPENDENCIES} "${target_depdendencies}" PARENT_SCOPE)
endfunction()
diff --git a/cmake/QtPublicSbomGenerationCycloneDXHelpers.cmake b/cmake/QtPublicSbomGenerationCycloneDXHelpers.cmake
new file mode 100644
index 00000000000..59797d24b7d
--- /dev/null
+++ b/cmake/QtPublicSbomGenerationCycloneDXHelpers.cmake
@@ -0,0 +1,425 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Helper to return the path to staging cydx file, where content will be incrementally appended to.
+function(_qt_internal_get_staging_area_cydx_file_path out_var)
+ _qt_internal_get_current_project_sbom_dir(sbom_dir)
+ _qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
+ set(staging_area_cydx_file "${sbom_dir}/staging-${repo_project_name_lowercase}.cdx.in.toml")
+ set(${out_var} "${staging_area_cydx_file}" PARENT_SCOPE)
+endfunction()
+
+# Starts recording information for the generation of a CycloneDX sbom for a project.
+# Similar to _qt_internal_sbom_begin_project_generate which is the SPDX variant.
+function(_qt_internal_sbom_begin_project_generate_cyclone)
+ set(opt_args "")
+ set(single_args
+ OUTPUT
+ OUTPUT_RELATIVE_PATH
+ LICENSE
+ COPYRIGHT
+ DOWNLOAD_LOCATION
+ PROJECT
+ PROJECT_COMMENT
+ PROJECT_FOR_SPDX_ID
+ SUPPLIER
+ SUPPLIER_URL
+ NAMESPACE
+ BOM_SERIAL_NUMBER_UUID
+ CPE
+ OUT_VAR_PROJECT_SPDX_ID
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ _qt_internal_forward_function_args(
+ FORWARD_PREFIX arg
+ FORWARD_OUT_VAR common_project_args
+ FORWARD_SINGLE
+ ${single_args}
+ )
+
+ _qt_internal_sbom_get_common_project_variables(
+ ${common_project_args}
+ OUT_VAR_PROJECT_NAME arg_PROJECT
+ OUT_VAR_CURRENT_UTC current_utc
+ OUT_VAR_CURRENT_YEAR current_year
+ DEFAULT_SBOM_FILE_NAME_EXTENSION "cdx"
+ OUT_VAR_OUTPUT arg_OUTPUT
+ OUT_VAR_OUTPUT_RELATIVE_PATH arg_OUTPUT_RELATIVE_PATH
+ OUT_VAR_PROJECT_FOR_SPDX_ID project_spdx_id
+ OUT_VAR_COPYRIGHT arg_COPYRIGHT
+ OUT_VAR_SUPPLIER arg_SUPPLIER
+ OUT_VAR_SUPPLIER_URL arg_SUPPLIER_URL
+ OUT_VAR_DEFAULT_PROJECT_COMMENT project_comment
+ )
+ if(arg_OUT_VAR_PROJECT_SPDX_ID)
+ set(${arg_OUT_VAR_PROJECT_SPDX_ID} "${project_spdx_id}" PARENT_SCOPE)
+ endif()
+
+ _qt_internal_sbom_get_git_version_vars()
+
+ _qt_internal_sbom_set_default_option_value_and_error_if_empty(BOM_SERIAL_NUMBER_UUID "")
+
+ if(arg_PROJECT_COMMENT)
+ string(APPEND project_comment "${arg_PROJECT_COMMENT}")
+ endif()
+
+ _qt_internal_sbom_set_default_option_value(DOWNLOAD_LOCATION "")
+ set(download_location_field "")
+ if(arg_DOWNLOAD_LOCATION)
+ set(download_location_field "download_location = \"${arg_DOWNLOAD_LOCATION}\"")
+ endif()
+
+ set(content "
+[root_component]
+name = \"${arg_PROJECT}\" # Required
+spdx_id = \"${project_spdx_id}\" # Required
+version = \"${QT_SBOM_GIT_VERSION}\" # Required
+supplier = '${arg_SUPPLIER}' # Required
+supplier_url = \"${arg_SUPPLIER_URL}\" # Required
+${download_location_field}
+build_date = \"${current_utc}\"
+serial_number_uuid = \"${arg_BOM_SERIAL_NUMBER_UUID}\" # Required
+description = '''${project_comment}
+'''
+
+[[project_build_tools]]
+name = \"cmake\"
+version = \"${CMAKE_VERSION}\"
+component_type = \"application\"
+description = \"Build system tool used to build the project.\"
+")
+
+ _qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
+ _qt_internal_sbom_create_sbom_staging_file(
+ CONTENT "${content}"
+ SBOM_FORMAT "CYDX_V1_6"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ OUT_VAR_CREATE_STAGING_FILE create_staging_file
+ OUT_VAR_SBOM_DIR sbom_dir
+ )
+
+ _qt_internal_sbom_save_project_info_in_global_properties(
+ SUPPLIER "${arg_SUPPLIER}"
+ SUPPLIER_URL "${arg_SUPPLIER_URL}"
+ NAMESPACE "${arg_NAMESPACE}"
+ PROJECT "${arg_PROJECT}"
+ PROJECT_SPDX_ID "${project_spdx_id}"
+ )
+
+ _qt_internal_sbom_save_common_path_variables_in_global_properties(
+ OUTPUT "${arg_OUTPUT}"
+ OUTPUT_RELATIVE_PATH "${arg_OUTPUT_RELATIVE_PATH}"
+ SBOM_DIR "${sbom_dir}"
+ PROPERTY_SUFFIX _cydx
+ )
+
+ set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_include_files_cydx "${create_staging_file}")
+endfunction()
+
+# Finalizes the CycloneDX sbom generation for a project.
+function(_qt_internal_sbom_end_project_generate_cyclone)
+ _qt_internal_sbom_get_common_path_variables_from_global_properties(
+ SBOM_FORMAT "CYDX_V1_6"
+ OUT_VAR_SBOM_BUILD_OUTPUT_PATH sbom_build_output_path
+ OUT_VAR_SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT sbom_build_output_path_without_ext
+ OUT_VAR_SBOM_BUILD_OUTPUT_DIR sbom_build_output_dir
+ OUT_VAR_SBOM_INSTALL_OUTPUT_PATH sbom_install_output_path
+ OUT_VAR_SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT sbom_install_output_path_without_ext
+ OUT_VAR_SBOM_INSTALL_OUTPUT_DIR sbom_install_output_dir
+ )
+
+ if(NOT sbom_build_output_path)
+ message(FATAL_ERROR "Call _qt_internal_sbom_begin_project() first")
+ endif()
+
+ _qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
+ _qt_internal_sbom_get_qt_repo_project_name_lower_case(real_qt_repo_project_name_lowercase)
+
+ # Process licenses before getting the includes.
+ _qt_internal_sbom_add_recorded_licenses_cydx()
+
+ _qt_internal_sbom_get_cmake_include_files(
+ SBOM_FORMAT "CYDX_V1_6"
+ OUT_VAR_INCLUDES includes
+ OUT_VAR_POST_GENERATION_INCLUDES post_generation_includes
+ )
+
+ _qt_internal_get_current_project_sbom_dir(sbom_dir)
+
+ set(build_time_args "")
+ if(includes)
+ list(APPEND build_time_args INCLUDES "${includes}")
+ endif()
+ if(post_generation_includes)
+ list(APPEND build_time_args POST_GENERATION_INCLUDES "${post_generation_includes}")
+ endif()
+ _qt_internal_sbom_create_build_time_sbom_targets(
+ SBOM_FORMAT "CYDX_V1_6"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ REAL_QT_REPO_PROJECT_NAME_LOWERCASE "${real_qt_repo_project_name_lowercase}"
+ SBOM_BUILD_OUTPUT_PATH "${sbom_build_output_path}"
+ SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT "${sbom_build_output_path_without_ext}"
+ SBOM_BUILD_OUTPUT_DIR "${sbom_build_output_dir}"
+ OUT_VAR_ASSEMBLE_SBOM_INCLUDE_PATH assemble_sbom
+ ${build_time_args}
+ )
+
+ _qt_internal_sbom_setup_multi_config_install_markers(
+ SBOM_DIR "${sbom_dir}"
+ SBOM_FORMAT "CYDX_V1_6"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ OUT_VAR_EXTRA_CODE_BEGIN extra_code_begin
+ OUT_VAR_EXTRA_CODE_INNER_END extra_code_inner_end
+ )
+
+ _qt_internal_sbom_setup_fake_checksum(
+ OUT_VAR_FAKE_CHECKSUM_CODE extra_code_begin_fake_checksum
+ )
+ if(extra_code_begin_fake_checksum)
+ string(APPEND extra_code_begin "${extra_code_begin_fake_checksum}")
+ endif()
+
+ set(setup_sbom_install_args "")
+ if(extra_code_begin)
+ list(APPEND setup_sbom_install_args EXTRA_CODE_BEGIN "${extra_code_begin}")
+ endif()
+ if(extra_code_inner_end)
+ list(APPEND setup_sbom_install_args EXTRA_CODE_INNER_END "${extra_code_inner_end}")
+ endif()
+ if(before_checksum_includes)
+ list(APPEND setup_sbom_install_args BEFORE_CHECKSUM_INCLUDES "${before_checksum_includes}")
+ endif()
+ if(after_checksum_includes)
+ list(APPEND setup_sbom_install_args AFTER_CHECKSUM_INCLUDES "${after_checksum_includes}")
+ endif()
+ if(post_generation_includes)
+ list(APPEND setup_sbom_install_args POST_GENERATION_INCLUDES "${post_generation_includes}")
+ endif()
+ if(verify_includes)
+ list(APPEND setup_sbom_install_args VERIFY_INCLUDES "${verify_includes}")
+ endif()
+
+ _qt_internal_sbom_setup_sbom_install_code(
+ SBOM_FORMAT "CYDX_V1_6"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ SBOM_INSTALL_OUTPUT_PATH "${sbom_install_output_path}"
+ SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT "${sbom_install_output_path_without_ext}"
+ SBOM_INSTALL_OUTPUT_DIR "${sbom_install_output_dir}"
+ ASSEMBLE_SBOM_INCLUDE_PATH "${assemble_sbom}"
+ ${setup_sbom_install_args}
+ )
+
+ _qt_internal_sbom_clear_cmake_include_files(
+ SBOM_FORMAT "CYDX_V1_6"
+ )
+endfunction()
+
+# Helper to add info about a package to the sbom. Usually a package is a mapping to a cmake target.
+function(_qt_internal_sbom_generate_cyclone_add_package)
+ set(opt_args "")
+ set(single_args
+ PACKAGE
+ VERSION
+ LICENSE_DECLARED
+ LICENSE_CONCLUDED
+ COPYRIGHT
+ DOWNLOAD_LOCATION
+ SPDXID
+ COMMENT
+
+ # Additions compared to spdx function signature.
+ CYDX_SUPPLIER
+ SBOM_ENTITY_TYPE
+ CONTAINING_COMPONENT
+ EXTERNAL_BOM_LINK
+ )
+ set(multi_args
+ CPE
+
+ # Additions compared to spdx function signature.
+ PURL_VALUES
+ DEPENDENCIES
+ CYDX_PROPERTIES
+ )
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ _qt_internal_sbom_set_default_option_value_and_error_if_empty(PACKAGE "")
+
+ set(check_option "")
+ if(arg_SPDXID)
+ set(check_option "CHECK" "${arg_SPDXID}")
+ endif()
+
+ _qt_internal_sbom_get_and_check_spdx_id(
+ VARIABLE arg_SPDXID
+ ${check_option}
+ HINTS "SPDXRef-${arg_PACKAGE}"
+ )
+
+ _qt_internal_sbom_set_default_option_value(DOWNLOAD_LOCATION "")
+ _qt_internal_sbom_set_default_option_value(VERSION "")
+ _qt_internal_sbom_set_default_option_value(SUPPLIER "")
+ _qt_internal_sbom_set_default_option_value(LICENSE_CONCLUDED "")
+ _qt_internal_sbom_set_default_option_value(COPYRIGHT "")
+
+ set(cpe_field "")
+ set(cpe_list ${arg_CPE})
+ if(cpe_list)
+ # Wrap values in double quotes.
+ list(TRANSFORM cpe_list PREPEND "\\\"")
+ list(TRANSFORM cpe_list APPEND "\\\"")
+ list(JOIN cpe_list ", " cpe_string)
+ set(cpe_field "cpe_list = [${cpe_string}]")
+ endif()
+
+ set(purl_field "")
+ set(purl_list ${arg_PURL_VALUES})
+ if(purl_list)
+ # Wrap values in double quotes.
+ list(TRANSFORM purl_list PREPEND "\\\"")
+ list(TRANSFORM purl_list APPEND "\\\"")
+ list(JOIN purl_list ", " purl_string)
+ set(purl_field "purl_list = [${purl_string}]")
+ endif()
+
+ set(name_field "name = \\\"${arg_PACKAGE}\\\"")
+ set(spdx_id_field "spdx_id = \\\"${arg_SPDXID}\\\"")
+ set(sbom_entity_type_field "sbom_entity_type = \\\"${arg_SBOM_ENTITY_TYPE}\\\"")
+
+ _qt_internal_sbom_get_cyclone_component_type(component_type "${arg_SBOM_ENTITY_TYPE}")
+ set(component_type_field "component_type = \\\"${component_type}\\\"")
+
+ set(version_field "")
+ if(arg_VERSION)
+ set(version_field "version = \\\"${arg_VERSION}\\\"")
+ endif()
+
+ set(dependency_field "")
+ set(dependency_list ${arg_DEPENDENCIES})
+ if(dependency_list)
+ # Wrap values in double quotes.
+ list(TRANSFORM dependency_list PREPEND "\\\"")
+ list(TRANSFORM dependency_list APPEND "\\\"")
+ list(JOIN dependency_list ", " dependency_string)
+ set(dependency_field "dependencies = [${dependency_string}]")
+ endif()
+
+ set(copyright_field "")
+ if(arg_COPYRIGHT)
+ set(copyright_field "copyright = '''${arg_COPYRIGHT}'''")
+ endif()
+
+ set(download_location_field "")
+ if(arg_DOWNLOAD_LOCATION)
+ set(download_location_field "download_location = \\\"${arg_DOWNLOAD_LOCATION}\\\"")
+ endif()
+
+ set(license_concluded_field "")
+ if(arg_LICENSE_CONCLUDED)
+ set(license_concluded_field
+ "license_concluded_expression = \\\"${arg_LICENSE_CONCLUDED}\\\"")
+ endif()
+
+ set(supplier_field "")
+ if(arg_CYDX_SUPPLIER)
+ set(supplier_field "supplier = '${arg_CYDX_SUPPLIER}'")
+ endif()
+
+ set(containing_component_field "")
+ if(arg_CONTAINING_COMPONENT)
+ set(containing_component_field "containing_component = \\\"${arg_CONTAINING_COMPONENT}\\\"")
+ endif()
+
+ set(external_bom_link_field "")
+ if(arg_EXTERNAL_BOM_LINK)
+ set(external_bom_link_field "external_bom_link = \\\"${arg_EXTERNAL_BOM_LINK}\\\"")
+ endif()
+
+ set(properties_field "")
+ if(arg_CYDX_PROPERTIES)
+ _qt_internal_sbom_handle_cydx_properties(
+ CYDX_PROPERTIES ${arg_CYDX_PROPERTIES}
+ OUT_VAR_CYDX_PROPERTIES_STRING properties_field
+ )
+ endif()
+
+ _qt_internal_get_staging_area_cydx_file_path(staging_area_spdx_file)
+
+ set(content "
+file(APPEND \"${staging_area_spdx_file}\"
+\"
+
+[[components]]
+${name_field}
+${spdx_id_field}
+${sbom_entity_type_field}
+${component_type_field}
+${version_field}
+${download_location_field}
+${copyright_field}
+${supplier_field}
+${containing_component_field}
+${external_bom_link_field}
+${cpe_field}
+${purl_field}
+${license_concluded_field}
+${dependency_field}
+${properties_field}
+\"
+)
+")
+
+ _qt_internal_get_current_project_sbom_dir(sbom_dir)
+ set(package_sbom "${sbom_dir}/cydx_${arg_SPDXID}.cmake")
+ file(GENERATE OUTPUT "${package_sbom}" CONTENT "${content}")
+
+ set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_include_files_cydx "${package_sbom}")
+endfunction()
+
+# Adds all recorded custom licenses to the toml file.
+function(_qt_internal_sbom_add_recorded_licenses_cydx)
+ get_property(license_ids GLOBAL PROPERTY _qt_internal_sbom_cydx_licenses)
+ if(NOT license_ids)
+ return()
+ endif()
+
+ set(content "")
+
+ foreach(license_id IN LISTS license_ids)
+ get_property(license_text GLOBAL PROPERTY
+ _qt_internal_sbom_cydx_licenses_${license_id}_text)
+
+ string(APPEND content "
+[[licenses]]
+license_id = \\\"${license_id}\\\"
+text = '''${license_text}
+'''
+")
+ endforeach()
+
+ _qt_internal_get_staging_area_cydx_file_path(staging_area_spdx_file)
+
+ set(content "
+file(APPEND \"${staging_area_spdx_file}\"
+\"
+${content}
+\"
+)
+")
+
+ _qt_internal_get_current_project_sbom_dir(sbom_dir)
+ set(snippet "${sbom_dir}/cydx_license_info.cmake")
+ file(GENERATE OUTPUT "${snippet}" CONTENT "${content}")
+
+ set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_end_include_files_cydx "${snippet}")
+
+ # Clean up before configuring next repo project.
+ set_property(GLOBAL PROPERTY _qt_internal_sbom_cydx_licenses "")
+ foreach(license_id IN LISTS license_ids)
+ set_property(GLOBAL PROPERTY _qt_internal_sbom_cydx_licenses_${license_id}_text "")
+ endforeach()
+endfunction()
diff --git a/cmake/QtPublicSbomGenerationHelpers.cmake b/cmake/QtPublicSbomGenerationHelpers.cmake
index 89179e77a1b..1ade46c950e 100644
--- a/cmake/QtPublicSbomGenerationHelpers.cmake
+++ b/cmake/QtPublicSbomGenerationHelpers.cmake
@@ -74,37 +74,36 @@ function(_qt_internal_sbom_begin_project_generate)
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
- if(QT_SBOM_FAKE_TIMESTAMP)
- set(current_utc "2590-01-01T11:33:55Z")
- set(current_year "2590")
- else()
- string(TIMESTAMP current_utc UTC)
- string(TIMESTAMP current_year "%Y" UTC)
- endif()
-
- _qt_internal_sbom_set_default_option_value(PROJECT "${PROJECT_NAME}")
-
- _qt_internal_sbom_get_git_version_vars()
-
- _qt_internal_path_join(default_sbom_file_name
- "${arg_PROJECT}" "${arg_PROJECT}-sbom-${QT_SBOM_GIT_VERSION_PATH}.spdx")
+ _qt_internal_forward_function_args(
+ FORWARD_PREFIX arg
+ FORWARD_OUT_VAR common_project_args
+ FORWARD_SINGLE
+ ${single_args}
+ )
- _qt_internal_path_join(default_install_sbom_path
- "\${CMAKE_INSTALL_PREFIX}/" "${CMAKE_INSTALL_DATAROOTDIR}" "${default_sbom_file_name}"
+ _qt_internal_sbom_get_common_project_variables(
+ ${common_project_args}
+ OUT_VAR_PROJECT_NAME arg_PROJECT
+ OUT_VAR_CURRENT_UTC current_utc
+ OUT_VAR_CURRENT_YEAR current_year
+ DEFAULT_SBOM_FILE_NAME_EXTENSION "spdx"
+ OUT_VAR_OUTPUT arg_OUTPUT
+ OUT_VAR_OUTPUT_RELATIVE_PATH arg_OUTPUT_RELATIVE_PATH
+ OUT_VAR_PROJECT_FOR_SPDX_ID project_spdx_id
+ OUT_VAR_COPYRIGHT arg_COPYRIGHT
+ OUT_VAR_SUPPLIER arg_SUPPLIER
+ OUT_VAR_SUPPLIER_URL arg_SUPPLIER_URL
+ OUT_VAR_DEFAULT_PROJECT_COMMENT project_comment
)
+ if(arg_OUT_VAR_PROJECT_SPDX_ID)
+ set(${arg_OUT_VAR_PROJECT_SPDX_ID} "${project_spdx_id}" PARENT_SCOPE)
+ endif()
- _qt_internal_sbom_set_default_option_value(OUTPUT "${default_install_sbom_path}")
- _qt_internal_sbom_set_default_option_value(OUTPUT_RELATIVE_PATH
- "${default_sbom_file_name}")
+ _qt_internal_sbom_get_git_version_vars()
- _qt_internal_sbom_set_default_option_value(LICENSE "NOASSERTION")
- _qt_internal_sbom_set_default_option_value(PROJECT_FOR_SPDX_ID "Package-${arg_PROJECT}")
- _qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER "")
- _qt_internal_sbom_set_default_option_value(COPYRIGHT "${current_year} ${arg_SUPPLIER}")
- _qt_internal_sbom_set_default_option_value_and_error_if_empty(SUPPLIER_URL
- "${PROJECT_HOMEPAGE_URL}")
_qt_internal_sbom_set_default_option_value(NAMESPACE
"${arg_SUPPLIER}/spdxdocs/${arg_PROJECT}-${QT_SBOM_GIT_VERSION}")
+ _qt_internal_sbom_set_default_option_value(LICENSE "NOASSERTION")
_qt_internal_sbom_set_default_option_value(DOCUMENT_CREATOR_TOOL "Qt Build System")
if(arg_DOCUMENT_CREATOR_TOOL)
@@ -132,34 +131,10 @@ ExternalRef: PACKAGE-MANAGER purl ${purl_generic_id}")
PackageVersion: ${QT_SBOM_GIT_VERSION}")
endif()
- string(REGEX REPLACE "[^A-Za-z0-9.]+" "-" arg_PROJECT_FOR_SPDX_ID "${arg_PROJECT_FOR_SPDX_ID}")
- string(REGEX REPLACE "-+$" "" arg_PROJECT_FOR_SPDX_ID "${arg_PROJECT_FOR_SPDX_ID}")
- # Prevent collision with other generated SPDXID with -[0-9]+ suffix.
- string(REGEX REPLACE "-([0-9]+)$" "\\1" arg_PROJECT_FOR_SPDX_ID "${arg_PROJECT_FOR_SPDX_ID}")
-
- set(project_spdx_id "SPDXRef-${arg_PROJECT_FOR_SPDX_ID}")
- if(arg_OUT_VAR_PROJECT_SPDX_ID)
- set(${arg_OUT_VAR_PROJECT_SPDX_ID} "${project_spdx_id}" PARENT_SCOPE)
- endif()
-
get_filename_component(doc_name "${arg_OUTPUT}" NAME_WLE)
- get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
- if(is_multi_config)
- set(cmake_configs "${CMAKE_CONFIGURATION_TYPES}")
- else()
- set(cmake_configs "${CMAKE_BUILD_TYPE}")
- endif()
-
_qt_internal_sbom_set_default_option_value(DOWNLOAD_LOCATION "NOASSERTION")
- set(cmake_version "Built by CMake ${CMAKE_VERSION}")
- set(system_name_and_processor "${CMAKE_SYSTEM_NAME} (${CMAKE_SYSTEM_PROCESSOR})")
- set(default_project_comment
- "${cmake_version} with ${cmake_configs} configuration for ${system_name_and_processor}")
-
- set(project_comment "${default_project_comment}")
-
if(arg_PROJECT_COMMENT)
string(APPEND project_comment "${arg_PROJECT_COMMENT}")
endif()
@@ -206,82 +181,30 @@ BuiltDate: ${current_utc}
Relationship: SPDXRef-DOCUMENT DESCRIBES ${project_spdx_id}
")
- # Create the directory that will contain all sbom related files.
- _qt_internal_get_current_project_sbom_dir(sbom_dir)
- file(MAKE_DIRECTORY "${sbom_dir}")
- set_property(GLOBAL APPEND PROPERTY _qt_internal_sbom_dirs "${sbom_dir}")
-
- # Generate project document intro spdx file.
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
- set(document_intro_file_name
- "${sbom_dir}/SPDXRef-DOCUMENT-${repo_project_name_lowercase}.spdx.in")
- file(GENERATE OUTPUT "${document_intro_file_name}" CONTENT "${content}")
-
- # This is the file that will be incrementally assembled by having content appended to it.
- _qt_internal_get_staging_area_spdx_file_path(staging_area_spdx_file)
-
- get_filename_component(output_file_name_without_ext "${arg_OUTPUT}" NAME_WLE)
- get_filename_component(output_file_ext "${arg_OUTPUT}" LAST_EXT)
-
- get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
- if(is_multi_config)
- set(multi_config_suffix "-$<CONFIG>")
- else()
- set(multi_config_suffix "")
- endif()
-
- set(computed_sbom_file_name_without_ext "${output_file_name_without_ext}${multi_config_suffix}")
- set(computed_sbom_file_name "${output_file_name_without_ext}${output_file_ext}")
-
- # In a super build and in a no-prefix build, put all the build time sboms into the same dir in,
- # in the qtbase build dir.
- if(QT_BUILDING_QT AND (QT_SUPERBUILD OR (NOT QT_WILL_INSTALL)))
- set(build_sbom_root_dir "${QT_BUILD_DIR}")
- else()
- set(build_sbom_root_dir "${sbom_dir}")
- endif()
-
- get_filename_component(output_relative_dir "${arg_OUTPUT_RELATIVE_PATH}" DIRECTORY)
-
- set(build_sbom_dir "${build_sbom_root_dir}/${output_relative_dir}")
- set(build_sbom_path "${build_sbom_dir}/${computed_sbom_file_name}")
- set(build_sbom_path_without_ext
- "${build_sbom_dir}/${computed_sbom_file_name_without_ext}")
-
- set(install_sbom_path "${arg_OUTPUT}")
-
- get_filename_component(install_sbom_dir "${install_sbom_path}" DIRECTORY)
- set(install_sbom_path_without_ext "${install_sbom_dir}/${output_file_name_without_ext}")
-
- # Create cmake file to append the document intro spdx to the staging file.
- set(create_staging_file "${sbom_dir}/append_document_to_staging${multi_config_suffix}.cmake")
- set(content "
- cmake_minimum_required(VERSION 3.16)
- message(STATUS \"Starting SBOM generation in build dir: ${staging_area_spdx_file}\")
- set(QT_SBOM_EXTERNAL_DOC_REFS \"\")
- file(READ \"${document_intro_file_name}\" content)
- # Override any previous file because we're starting from scratch.
- file(WRITE \"${staging_area_spdx_file}\" \"\${content}\")
-")
- file(GENERATE OUTPUT "${create_staging_file}" CONTENT "${content}")
-
-
- set_property(GLOBAL PROPERTY _qt_sbom_project_supplier "${arg_SUPPLIER}")
- set_property(GLOBAL PROPERTY _qt_sbom_project_supplier_url "${arg_SUPPLIER_URL}")
- set_property(GLOBAL PROPERTY _qt_sbom_project_namespace "${arg_NAMESPACE}")
+ _qt_internal_sbom_create_sbom_staging_file(
+ CONTENT "${content}"
+ SBOM_FORMAT "SPDX_V2"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ OUT_VAR_CREATE_STAGING_FILE create_staging_file
+ OUT_VAR_SBOM_DIR sbom_dir
+ )
- set_property(GLOBAL PROPERTY _qt_sbom_project_name "${arg_PROJECT}")
- set_property(GLOBAL PROPERTY _qt_sbom_project_spdx_id "${project_spdx_id}")
+ set_property(GLOBAL APPEND PROPERTY _qt_internal_sbom_dirs "${sbom_dir}")
- set_property(GLOBAL PROPERTY _qt_sbom_build_output_path "${build_sbom_path}")
- set_property(GLOBAL PROPERTY _qt_sbom_build_output_path_without_ext
- "${build_sbom_path_without_ext}")
- set_property(GLOBAL PROPERTY _qt_sbom_build_output_dir "${build_sbom_dir}")
+ _qt_internal_sbom_save_project_info_in_global_properties(
+ SUPPLIER "${arg_SUPPLIER}"
+ SUPPLIER_URL "${arg_SUPPLIER_URL}"
+ NAMESPACE "${arg_NAMESPACE}"
+ PROJECT "${arg_PROJECT}"
+ PROJECT_SPDX_ID "${project_spdx_id}"
+ )
- set_property(GLOBAL PROPERTY _qt_sbom_install_output_path "${install_sbom_path}")
- set_property(GLOBAL PROPERTY _qt_sbom_install_output_path_without_ext
- "${install_sbom_path_without_ext}")
- set_property(GLOBAL PROPERTY _qt_sbom_install_output_dir "${install_sbom_dir}")
+ _qt_internal_sbom_save_common_path_variables_in_global_properties(
+ OUTPUT "${arg_OUTPUT}"
+ OUTPUT_RELATIVE_PATH "${arg_OUTPUT_RELATIVE_PATH}"
+ SBOM_DIR "${sbom_dir}"
+ )
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_include_files "${create_staging_file}")
@@ -293,116 +216,51 @@ endfunction()
# Creates an 'sbom' custom target to generate an incomplete sbom at build time (no checksums).
# Creates install rules to install a complete (with checksums) sbom.
function(_qt_internal_sbom_end_project_generate)
- get_property(sbom_build_output_path GLOBAL PROPERTY _qt_sbom_build_output_path)
- get_property(sbom_build_output_path_without_ext GLOBAL PROPERTY
- _qt_sbom_build_output_path_without_ext)
- get_property(sbom_build_output_dir GLOBAL PROPERTY _qt_sbom_build_output_dir)
-
- get_property(sbom_install_output_path GLOBAL PROPERTY _qt_sbom_install_output_path)
- get_property(sbom_install_output_path_without_ext GLOBAL PROPERTY
- _qt_sbom_install_output_path_without_ext)
- get_property(sbom_install_output_dir GLOBAL PROPERTY _qt_sbom_install_output_dir)
+ _qt_internal_sbom_get_common_path_variables_from_global_properties(
+ SBOM_FORMAT "SPDX_V2"
+ OUT_VAR_SBOM_BUILD_OUTPUT_PATH sbom_build_output_path
+ OUT_VAR_SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT sbom_build_output_path_without_ext
+ OUT_VAR_SBOM_BUILD_OUTPUT_DIR sbom_build_output_dir
+ OUT_VAR_SBOM_INSTALL_OUTPUT_PATH sbom_install_output_path
+ OUT_VAR_SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT sbom_install_output_path_without_ext
+ OUT_VAR_SBOM_INSTALL_OUTPUT_DIR sbom_install_output_dir
+ )
if(NOT sbom_build_output_path)
message(FATAL_ERROR "Call _qt_internal_sbom_begin_project() first")
endif()
- _qt_internal_get_staging_area_spdx_file_path(staging_area_spdx_file)
-
- _qt_internal_sbom_collect_cmake_include_files(includes
- JOIN_WITH_NEWLINES
- PROPERTIES _qt_sbom_cmake_include_files _qt_sbom_cmake_end_include_files
- )
-
- # Before checksum includes are included after the verification codes have been collected
- # and before their merged checksum(s) has been computed.
- _qt_internal_sbom_collect_cmake_include_files(before_checksum_includes
- JOIN_WITH_NEWLINES
- PROPERTIES _qt_sbom_cmake_before_checksum_include_files
- )
-
- # After checksum includes are included after the checksum has been computed and written to the
- # QT_SBOM_VERIFICATION_CODE variable.
- _qt_internal_sbom_collect_cmake_include_files(after_checksum_includes
- JOIN_WITH_NEWLINES
- PROPERTIES _qt_sbom_cmake_after_checksum_include_files
- )
-
- # Post generation includes are included for both build and install time sboms, after
- # sbom generation has finished.
- _qt_internal_sbom_collect_cmake_include_files(post_generation_includes
- JOIN_WITH_NEWLINES
- PROPERTIES _qt_sbom_cmake_post_generation_include_files
- )
+ _qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
+ _qt_internal_sbom_get_qt_repo_project_name_lower_case(real_qt_repo_project_name_lowercase)
- # Verification only makes sense on installation, where the checksums are present.
- _qt_internal_sbom_collect_cmake_include_files(verify_includes
- JOIN_WITH_NEWLINES
- PROPERTIES _qt_sbom_cmake_verify_include_files
+ _qt_internal_sbom_get_cmake_include_files(
+ SBOM_FORMAT "SPDX_V2"
+ OUT_VAR_INCLUDES includes
+ OUT_VAR_BEFORE_CHECKSUM_INCLUDES before_checksum_includes
+ OUT_VAR_AFTER_CHECKSUM_INCLUDES after_checksum_includes
+ OUT_VAR_POST_GENERATION_INCLUDES post_generation_includes
+ OUT_VAR_VERIFY_INCLUDES verify_includes
)
- get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
- if(is_multi_config)
- set(multi_config_suffix "-$<CONFIG>")
- else()
- set(multi_config_suffix "")
- endif()
-
_qt_internal_get_current_project_sbom_dir(sbom_dir)
- set(content "
- # QT_SBOM_BUILD_TIME be set to FALSE at install time, so don't override if it's set.
- # This allows reusing the same cmake file for both build and install.
- if(NOT DEFINED QT_SBOM_BUILD_TIME)
- set(QT_SBOM_BUILD_TIME TRUE)
- endif()
- if(NOT QT_SBOM_OUTPUT_PATH)
- set(QT_SBOM_OUTPUT_DIR \"${sbom_build_output_dir}\")
- set(QT_SBOM_OUTPUT_PATH \"${sbom_build_output_path}\")
- set(QT_SBOM_OUTPUT_PATH_WITHOUT_EXT \"${sbom_build_output_path_without_ext}\")
- file(MAKE_DIRECTORY \"${sbom_build_output_dir}\")
- endif()
- set(QT_SBOM_PACKAGES \"\")
- set(QT_SBOM_PACKAGES_WITH_VERIFICATION_CODES \"\")
- ${includes}
- if(QT_SBOM_BUILD_TIME)
- message(STATUS \"Finalizing SBOM generation in build dir: \${QT_SBOM_OUTPUT_PATH}\")
- configure_file(\"${staging_area_spdx_file}\" \"\${QT_SBOM_OUTPUT_PATH}\")
- ${post_generation_includes}
- endif()
-")
- set(assemble_sbom "${sbom_dir}/assemble_sbom${multi_config_suffix}.cmake")
- file(GENERATE OUTPUT "${assemble_sbom}" CONTENT "${content}")
- if(NOT TARGET sbom)
- add_custom_target(sbom)
+ set(build_time_args "")
+ if(includes)
+ list(APPEND build_time_args INCLUDES "${includes}")
endif()
-
- _qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
- _qt_internal_sbom_get_qt_repo_project_name_lower_case(real_qt_repo_project_name_lowercase)
-
- # Create a build target to create a build-time sbom (no verification codes or sha1s).
- set(repo_sbom_target "sbom_${repo_project_name_lowercase}")
- set(comment "")
- string(APPEND comment "Assembling build time SPDX document without checksums for "
- "${repo_project_name_lowercase}. Just for testing.")
- add_custom_target(${repo_sbom_target}
- COMMAND "${CMAKE_COMMAND}" -P "${assemble_sbom}"
- COMMENT "${comment}"
- VERBATIM
- USES_TERMINAL # To avoid running two configs of the command in parallel
- )
-
- get_cmake_property(qt_repo_deps _qt_repo_deps_${real_qt_repo_project_name_lowercase})
- if(qt_repo_deps)
- foreach(repo_dep IN LISTS qt_repo_deps)
- set(repo_dep_sbom "sbom_${repo_dep}")
- if(TARGET "${repo_dep_sbom}")
- add_dependencies(${repo_sbom_target} ${repo_dep_sbom})
- endif()
- endforeach()
+ if(post_generation_includes)
+ list(APPEND build_time_args POST_GENERATION_INCLUDES "${post_generation_includes}")
endif()
-
- add_dependencies(sbom ${repo_sbom_target})
+ _qt_internal_sbom_create_build_time_sbom_targets(
+ SBOM_FORMAT "SPDX_V2"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ REAL_QT_REPO_PROJECT_NAME_LOWERCASE "${real_qt_repo_project_name_lowercase}"
+ SBOM_BUILD_OUTPUT_PATH "${sbom_build_output_path}"
+ SBOM_BUILD_OUTPUT_PATH_WITHOUT_EXT "${sbom_build_output_path_without_ext}"
+ SBOM_BUILD_OUTPUT_DIR "${sbom_build_output_dir}"
+ OUT_VAR_ASSEMBLE_SBOM_INCLUDE_PATH assemble_sbom
+ ${build_time_args}
+ )
# Add 'reuse lint' per-repo custom targets.
if(arg_LINT_SOURCE_SBOM AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
@@ -420,59 +278,19 @@ function(_qt_internal_sbom_end_project_generate)
add_dependencies(reuse_lint ${repo_sbom_target}_reuse_lint)
endif()
- set(extra_code_begin "")
- set(extra_code_inner_end "")
-
- get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
- if(is_multi_config)
- set(configs ${CMAKE_CONFIGURATION_TYPES})
-
- set(install_markers_dir "${sbom_dir}")
- set(install_marker_path "${install_markers_dir}/finished_install-$<CONFIG>.cmake")
-
- set(install_marker_code "
- message(STATUS \"Writing install marker for config $<CONFIG>: ${install_marker_path} \")
- file(WRITE \"${install_marker_path}\" \"\")
-")
-
- install(CODE "${install_marker_code}" COMPONENT sbom)
- if(QT_SUPERBUILD)
- install(CODE "${install_marker_code}" COMPONENT "sbom_${repo_project_name_lowercase}"
- EXCLUDE_FROM_ALL)
- endif()
-
- set(install_markers "")
- foreach(config IN LISTS configs)
- set(marker_path "${install_markers_dir}/finished_install-${config}.cmake")
- list(APPEND install_markers "${marker_path}")
- # Remove the markers on reconfiguration, just in case there are stale ones.
- if(EXISTS "${marker_path}")
- file(REMOVE "${marker_path}")
- endif()
- endforeach()
-
- set(extra_code_begin "
- set(QT_SBOM_INSTALL_MARKERS \"${install_markers}\")
- foreach(QT_SBOM_INSTALL_MARKER IN LISTS QT_SBOM_INSTALL_MARKERS)
- if(NOT EXISTS \"\${QT_SBOM_INSTALL_MARKER}\")
- set(QT_SBOM_INSTALLED_ALL_CONFIGS FALSE)
- endif()
- endforeach()
-")
- set(extra_code_inner_end "
- foreach(QT_SBOM_INSTALL_MARKER IN LISTS QT_SBOM_INSTALL_MARKERS)
- message(STATUS
- \"Removing install marker: \${QT_SBOM_INSTALL_MARKER} \")
- file(REMOVE \"\${QT_SBOM_INSTALL_MARKER}\")
- endforeach()
-")
- endif()
+ _qt_internal_sbom_setup_multi_config_install_markers(
+ SBOM_DIR "${sbom_dir}"
+ SBOM_FORMAT "SPDX_V2"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ OUT_VAR_EXTRA_CODE_BEGIN extra_code_begin
+ OUT_VAR_EXTRA_CODE_INNER_END extra_code_inner_end
+ )
- # Allow skipping checksum computation for testing purposes, while installing just the sbom
- # documents, without requiring to build and install all the actual files.
- if(QT_SBOM_FAKE_CHECKSUM)
- string(APPEND extra_code_begin "
- set(QT_SBOM_FAKE_CHECKSUM TRUE)")
+ _qt_internal_sbom_setup_fake_checksum(
+ OUT_VAR_FAKE_CHECKSUM_CODE extra_code_begin_fake_checksum
+ )
+ if(extra_code_begin_fake_checksum)
+ string(APPEND extra_code_begin "${extra_code_begin_fake_checksum}")
endif()
set(verification_codes_content "
@@ -496,42 +314,40 @@ unset(_verification_code)
set(process_verification_codes "${sbom_dir}/process_verification_codes.cmake")
file(GENERATE OUTPUT "${process_verification_codes}" CONTENT "${verification_codes_content}")
- set(assemble_sbom_install "
- set(QT_SBOM_INSTALLED_ALL_CONFIGS TRUE)
- ${extra_code_begin}
- if(QT_SBOM_INSTALLED_ALL_CONFIGS)
- set(QT_SBOM_BUILD_TIME FALSE)
- set(QT_SBOM_OUTPUT_DIR \"${sbom_install_output_dir}\")
- set(QT_SBOM_OUTPUT_PATH \"${sbom_install_output_path}\")
- set(QT_SBOM_OUTPUT_PATH_WITHOUT_EXT \"${sbom_install_output_path_without_ext}\")
- file(MAKE_DIRECTORY \"${sbom_install_output_dir}\")
- include(\"${assemble_sbom}\")
- ${before_checksum_includes}
- include(\"${process_verification_codes}\")
- ${after_checksum_includes}
- message(STATUS \"Finalizing SBOM generation in install dir: \${QT_SBOM_OUTPUT_PATH}\")
- configure_file(\"${staging_area_spdx_file}\" \"\${QT_SBOM_OUTPUT_PATH}\")
- ${post_generation_includes}
- ${verify_includes}
- ${extra_code_inner_end}
- else()
- message(STATUS \"Skipping SBOM finalization because not all configs were installed.\")
- endif()
-")
-
- install(CODE "${assemble_sbom_install}" COMPONENT sbom)
- if(QT_SUPERBUILD)
- install(CODE "${assemble_sbom_install}" COMPONENT "sbom_${repo_project_name_lowercase}"
- EXCLUDE_FROM_ALL)
+ set(setup_sbom_install_args "")
+ if(extra_code_begin)
+ list(APPEND setup_sbom_install_args EXTRA_CODE_BEGIN "${extra_code_begin}")
+ endif()
+ if(extra_code_inner_end)
+ list(APPEND setup_sbom_install_args EXTRA_CODE_INNER_END "${extra_code_inner_end}")
+ endif()
+ if(before_checksum_includes)
+ list(APPEND setup_sbom_install_args BEFORE_CHECKSUM_INCLUDES "${before_checksum_includes}")
+ endif()
+ if(after_checksum_includes)
+ list(APPEND setup_sbom_install_args AFTER_CHECKSUM_INCLUDES "${after_checksum_includes}")
+ endif()
+ if(post_generation_includes)
+ list(APPEND setup_sbom_install_args POST_GENERATION_INCLUDES "${post_generation_includes}")
+ endif()
+ if(verify_includes)
+ list(APPEND setup_sbom_install_args VERIFY_INCLUDES "${verify_includes}")
endif()
- # Clean up properties, so that they are empty for possible next repo in a top-level build.
- set_property(GLOBAL PROPERTY _qt_sbom_cmake_include_files "")
- set_property(GLOBAL PROPERTY _qt_sbom_cmake_end_include_files "")
- set_property(GLOBAL PROPERTY _qt_sbom_cmake_before_checksum_include_files "")
- set_property(GLOBAL PROPERTY _qt_sbom_cmake_after_checksum_include_files "")
- set_property(GLOBAL PROPERTY _qt_sbom_cmake_post_generation_include_files "")
- set_property(GLOBAL PROPERTY _qt_sbom_cmake_verify_include_files "")
+ _qt_internal_sbom_setup_sbom_install_code(
+ SBOM_FORMAT "SPDX_V2"
+ REPO_PROJECT_NAME_LOWERCASE "${repo_project_name_lowercase}"
+ SBOM_INSTALL_OUTPUT_PATH "${sbom_install_output_path}"
+ SBOM_INSTALL_OUTPUT_PATH_WITHOUT_EXT "${sbom_install_output_path_without_ext}"
+ SBOM_INSTALL_OUTPUT_DIR "${sbom_install_output_dir}"
+ ASSEMBLE_SBOM_INCLUDE_PATH "${assemble_sbom}"
+ PROCESS_VERIFICATION_CODES "${process_verification_codes}"
+ ${setup_sbom_install_args}
+ )
+
+ _qt_internal_sbom_clear_cmake_include_files(
+ SBOM_FORMAT "SPDX_V2"
+ )
endfunction()
# Gets a list of cmake include file paths, joins them as include() statements and returns the
diff --git a/cmake/QtPublicSbomHelpers.cmake b/cmake/QtPublicSbomHelpers.cmake
index 1a8702bf594..3d66e7ff783 100644
--- a/cmake/QtPublicSbomHelpers.cmake
+++ b/cmake/QtPublicSbomHelpers.cmake
@@ -85,7 +85,8 @@ function(_qt_internal_sbom_begin_project)
_qt_internal_sbom_get_root_project_name_for_spdx_id(repo_project_name_for_spdx_id)
_qt_internal_sbom_get_root_project_name_lower_case(repo_project_name_lowercase)
- set(begin_project_generate_args "")
+ set(begin_project_generate_args_spdx "")
+ set(begin_project_generate_args_cydx "")
if(arg_SUPPLIER_URL)
set(repo_supplier_url "${arg_SUPPLIER_URL}")
@@ -93,7 +94,8 @@ function(_qt_internal_sbom_begin_project)
_qt_internal_sbom_get_default_supplier_url(repo_supplier_url)
endif()
if(repo_supplier_url)
- list(APPEND begin_project_generate_args SUPPLIER_URL "${repo_supplier_url}")
+ list(APPEND begin_project_generate_args_spdx SUPPLIER_URL "${repo_supplier_url}")
+ list(APPEND begin_project_generate_args_cydx SUPPLIER_URL "${repo_supplier_url}")
endif()
set(sbom_project_version_args "")
@@ -121,6 +123,15 @@ function(_qt_internal_sbom_begin_project)
)
endif()
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ _qt_internal_sbom_get_cyclone_bom_serial_number(
+ SPDX_NAMESPACE "${repo_spdx_namespace}"
+ OUT_VAR_UUID cyclone_dx_bom_serial_number_uuid
+ )
+ list(APPEND begin_project_generate_args_cydx
+ BOM_SERIAL_NUMBER_UUID "${cyclone_dx_bom_serial_number_uuid}")
+ endif()
+
if(arg_INSTALL_SBOM_DIR)
set(install_sbom_dir "${arg_INSTALL_SBOM_DIR}")
elseif(INSTALL_SBOMDIR)
@@ -143,17 +154,28 @@ function(_qt_internal_sbom_begin_project)
list(APPEND compute_project_file_name_args VERSION_SUFFIX "${explicit_version}")
endif()
- _qt_internal_sbom_compute_project_file_name(repo_project_file_name
+ _qt_internal_sbom_compute_project_file_name(repo_project_file_name_spdx
+ SPDX_TAG_VALUE
+ PROJECT_NAME "${repo_project_name_lowercase}"
+ ${compute_project_file_name_args}
+ )
+
+ _qt_internal_sbom_compute_project_file_name(repo_project_file_name_cydx
+ CYCLONEDX_TOML
PROJECT_NAME "${repo_project_name_lowercase}"
${compute_project_file_name_args}
)
- _qt_internal_path_join(repo_spdx_relative_install_path
- "${arg_INSTALL_SBOM_DIR}" "${repo_project_file_name}")
+ _qt_internal_path_join(repo_spdx_relative_install_path_spdx
+ "${install_sbom_dir}" "${repo_project_file_name_spdx}")
+ _qt_internal_path_join(repo_spdx_relative_install_path_cydx
+ "${install_sbom_dir}" "${repo_project_file_name_cydx}")
# Prepend DESTDIR, to allow relocating installed sbom. Needed for CI.
- _qt_internal_path_join(repo_spdx_install_path
- "\$ENV{DESTDIR}${install_prefix}" "${repo_spdx_relative_install_path}")
+ _qt_internal_path_join(repo_spdx_install_path_spdx
+ "\$ENV{DESTDIR}${install_prefix}" "${repo_spdx_relative_install_path_spdx}")
+ _qt_internal_path_join(repo_spdx_install_path_cydx
+ "\$ENV{DESTDIR}${install_prefix}" "${repo_spdx_relative_install_path_cydx}")
if(arg_LICENSE_EXPRESSION)
set(repo_license "${arg_LICENSE_EXPRESSION}")
@@ -164,7 +186,8 @@ function(_qt_internal_sbom_begin_project)
set(repo_license "")
endif()
if(repo_license)
- list(APPEND begin_project_generate_args LICENSE "${repo_license}")
+ list(APPEND begin_project_generate_args_spdx LICENSE "${repo_license}")
+ list(APPEND begin_project_generate_args_cydx LICENSE "${repo_license}")
endif()
if(arg_COPYRIGHTS)
@@ -174,7 +197,8 @@ function(_qt_internal_sbom_begin_project)
_qt_internal_sbom_get_default_qt_copyright_header(repo_copyright)
endif()
if(repo_copyright)
- list(APPEND begin_project_generate_args COPYRIGHT "${repo_copyright}")
+ list(APPEND begin_project_generate_args_spdx COPYRIGHT "${repo_copyright}")
+ list(APPEND begin_project_generate_args_cydx COPYRIGHT "${repo_copyright}")
endif()
if(arg_SUPPLIER)
@@ -184,7 +208,8 @@ function(_qt_internal_sbom_begin_project)
endif()
if(repo_supplier)
# This must not contain spaces!
- list(APPEND begin_project_generate_args SUPPLIER "${repo_supplier}")
+ list(APPEND begin_project_generate_args_spdx SUPPLIER "${repo_supplier}")
+ list(APPEND begin_project_generate_args_cydx SUPPLIER "${repo_supplier}")
endif()
if(arg_CPE)
@@ -195,7 +220,8 @@ function(_qt_internal_sbom_begin_project)
set(qt_cpe "")
endif()
if(qt_cpe)
- list(APPEND begin_project_generate_args CPE "${qt_cpe}")
+ list(APPEND begin_project_generate_args_spdx CPE "${qt_cpe}")
+ list(APPEND begin_project_generate_args_cydx CPE "${qt_cpe}")
endif()
if(arg_DOWNLOAD_LOCATION)
@@ -204,11 +230,12 @@ function(_qt_internal_sbom_begin_project)
_qt_internal_sbom_get_qt_repo_source_download_location(download_location)
endif()
if(download_location)
- list(APPEND begin_project_generate_args DOWNLOAD_LOCATION "${download_location}")
+ list(APPEND begin_project_generate_args_spdx DOWNLOAD_LOCATION "${download_location}")
+ list(APPEND begin_project_generate_args_cydx DOWNLOAD_LOCATION "${download_location}")
endif()
if(arg_DOCUMENT_CREATOR_TOOL)
- list(APPEND begin_project_generate_args
+ list(APPEND begin_project_generate_args_spdx
DOCUMENT_CREATOR_TOOL "${arg_DOCUMENT_CREATOR_TOOL}")
endif()
@@ -229,24 +256,42 @@ function(_qt_internal_sbom_begin_project)
set(project_comment PROJECT_COMMENT "${project_comment}")
endif()
- _qt_internal_sbom_begin_project_generate(
- OUTPUT "${repo_spdx_install_path}"
- OUTPUT_RELATIVE_PATH "${repo_spdx_relative_install_path}"
- PROJECT "${repo_project_name_lowercase}"
- ${project_comment}
- PROJECT_FOR_SPDX_ID "${repo_project_name_for_spdx_id}"
- NAMESPACE "${repo_spdx_namespace}"
- ${begin_project_generate_args}
- OUT_VAR_PROJECT_SPDX_ID repo_project_spdx_id
- )
+ if(QT_SBOM_GENERATE_SPDX_V2)
+ _qt_internal_sbom_begin_project_generate(
+ OUTPUT "${repo_spdx_install_path_spdx}"
+ OUTPUT_RELATIVE_PATH "${repo_spdx_relative_install_path_spdx}"
+ PROJECT "${repo_project_name_lowercase}"
+ ${project_comment}
+ PROJECT_FOR_SPDX_ID "${repo_project_name_for_spdx_id}"
+ NAMESPACE "${repo_spdx_namespace}"
+ ${begin_project_generate_args_spdx}
+ OUT_VAR_PROJECT_SPDX_ID repo_project_spdx_id
+ )
+ endif()
+
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ _qt_internal_sbom_begin_project_generate_cyclone(
+ OUTPUT "${repo_spdx_install_path_cydx}"
+ OUTPUT_RELATIVE_PATH "${repo_spdx_relative_install_path_cydx}"
+ PROJECT "${repo_project_name_lowercase}"
+ ${project_comment}
+ PROJECT_FOR_SPDX_ID "${repo_project_name_for_spdx_id}"
+ NAMESPACE "${repo_spdx_namespace}"
+ ${begin_project_generate_args_cydx}
+ OUT_VAR_PROJECT_SPDX_ID repo_project_spdx_id
+ )
+ endif()
set_property(GLOBAL PROPERTY _qt_internal_project_attribution_files "")
set_property(GLOBAL PROPERTY _qt_internal_sbom_repo_document_namespace
"${repo_spdx_namespace}")
+ set_property(GLOBAL PROPERTY _qt_internal_sbom_repo_cyclone_dx_bom_serial_number_uuid
+ "${cyclone_dx_bom_serial_number_uuid}")
+
set_property(GLOBAL PROPERTY _qt_internal_sbom_relative_installed_repo_document_path
- "${repo_spdx_relative_install_path}")
+ "${repo_spdx_relative_install_path_spdx}")
set_property(GLOBAL PROPERTY _qt_internal_sbom_repo_project_name_lowercase
"${repo_project_name_lowercase}")
@@ -312,7 +357,10 @@ endfunction()
function(_qt_internal_sbom_setup_project_ops)
set(options "")
- if(QT_SBOM_GENERATE_JSON OR QT_INTERNAL_SBOM_GENERATE_JSON OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
+ if(QT_SBOM_GENERATE_JSON
+ OR QT_SBOM_GENERATE_SPDX_V2_JSON
+ OR QT_INTERNAL_SBOM_GENERATE_JSON
+ OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND options GENERATE_JSON)
endif()
@@ -320,20 +368,48 @@ function(_qt_internal_sbom_setup_project_ops)
# The user can explicitly request to fail the build if dependencies are not found.
# error out. For internal options that the CI uses, we always want to fail the build if the
# deps are not found.
- if(QT_SBOM_REQUIRE_GENERATE_JSON OR QT_INTERNAL_SBOM_GENERATE_JSON
+ if(QT_SBOM_REQUIRE_GENERATE_JSON
+ OR QT_SBOM_REQUIRE_GENERATE_SPDX_V2_JSON
+ OR QT_INTERNAL_SBOM_GENERATE_JSON
OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND options GENERATE_JSON_REQUIRED)
endif()
- if(QT_SBOM_VERIFY OR QT_INTERNAL_SBOM_VERIFY OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
+ if(QT_SBOM_VERIFY
+ OR QT_SBOM_VERIFY_SPDX_V2
+ OR QT_INTERNAL_SBOM_VERIFY
+ OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND options VERIFY_SBOM)
endif()
# Do the same requirement check for SBOM verification.
- if(QT_SBOM_REQUIRE_VERIFY OR QT_INTERNAL_SBOM_VERIFY OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
+ if(QT_SBOM_REQUIRE_VERIFY
+ OR QT_SBOM_REQUIRE_VERIFY_SPDX_V2
+ OR QT_INTERNAL_SBOM_VERIFY
+ OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND options VERIFY_SBOM_REQUIRED)
endif()
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ list(APPEND options GENERATE_CYCLONE_DX_V1_6)
+ endif()
+
+ if(QT_SBOM_REQUIRE_GENERATE_CYDX_V1_6)
+ list(APPEND options GENERATE_CYCLONE_DX_V1_6_REQUIRED)
+ endif()
+
+ if(QT_SBOM_VERIFY_CYDX_V1_6)
+ list(APPEND options VERIFY_CYCLONE_DX_V1_6)
+ endif()
+
+ if(QT_SBOM_REQUIRE_VERIFY_CYDX_V1_6)
+ list(APPEND options VERIFY_CYCLONE_DX_V1_6_REQUIRED)
+ endif()
+
+ if(QT_SBOM_VERBOSE_CYDX_V1_6)
+ list(APPEND options VERBOSE_CYCLONE_DX_V1_6)
+ endif()
+
if(QT_SBOM_VERIFY_NTIA_COMPLIANT
OR QT_INTERNAL_SBOM_VERIFY_NTIA_COMPLIANT OR QT_INTERNAL_SBOM_DEFAULT_CHECKS)
list(APPEND options VERIFY_NTIA_COMPLIANT)
@@ -367,12 +443,20 @@ function(_qt_internal_sbom_setup_project_ops)
endfunction()
# Sets up SBOM generation and verification options.
-# By default SBOM generation is disabled.
-# By default JSON generation and SBOM verification are enabled by default, if the dependencies
-# are present, otherwise they will be silently skipped. Unless the user explicitly requests to
-# fail the build if the dependencies are not found.
#
-# The QT_GENERATE_SBOM_DEFAULT option can be set by a project to change the default value.
+# By default, the main toggle for SBOM generation is disabled. The GENERATE_SBOM_DEFAULT option
+# overrides that value and can be set by a project that sets up SBOM generation.
+#
+# If the main toggle gets enabled, we enable SPDX V2.3 tag:value generation, and try to enable
+# CycloneDX V1.6 generation. Try, because CDX generation needs python dependencies. If they are
+# not found, the generation is silently skipped.
+#
+# By default SPDX v2.3 JSON generation and verification is enabled, if the python dependencies
+# are found. Otherwise they will be silently skipped.
+# Unless the user explicitly requests to fail the build if the dependencies are not found.
+# The same can be done for CycloneDX generation.
+#
+# Some older variables that were added pre-CycloneDX generation are deprecated.
function(_qt_internal_setup_sbom)
set(opt_args "")
set(single_args
@@ -388,22 +472,159 @@ function(_qt_internal_setup_sbom)
set(default_value "${arg_GENERATE_SBOM_DEFAULT}")
endif()
- option(QT_GENERATE_SBOM "Generate SBOM documents in SPDX v2.3 tag:value format."
- "${default_value}")
+ # Main SBOM toggle. Used to be the toggle for SPDX v2.3 only, but now would also enable Cyclone
+ # DX as well.
+ set(sbom_help_string "Generate SBOM.")
+ option(QT_GENERATE_SBOM "${sbom_help_string}" "${default_value}")
+
+
+ # Toggle for SPDX V2.3 generation.
+ set(spdx_v2_help_string "Generate SBOM documents in SPDX v2.3 tag:value format.")
+ option(QT_SBOM_GENERATE_SPDX_V2 "${spdx_v2_help_string}" ON)
+
+
+ # Toggles for CycloneDX V1.6 generation.
+ set(cydx_help_string "Generate SBOM documents in CycloneDX v1.6 JSON format.")
+ option(QT_SBOM_GENERATE_CYDX_V1_6 "${cydx_help_string}" ON)
- string(CONCAT help_string
+ set(cydx_require_help_string
+ "Error out if CycloneDX SBOM generation dependencies are not found.")
+ option(QT_SBOM_REQUIRE_GENERATE_CYDX_V1_6 "${cydx_require_help_string}" OFF)
+
+
+ # Options for SPDX v2.3 JSON generation and verification.
+
+ string(CONCAT spdx_v23_json_help_string
"Generate SBOM documents in SPDX v2.3 JSON format if required python dependency "
- "spdx-tools is available"
+ "spdx-tools is available."
)
- option(QT_SBOM_GENERATE_JSON
- "${help_string}" ON)
- option(QT_SBOM_REQUIRE_GENERATE_JSON
- "Error out if JSON SBOM generation depdendency is not found." OFF)
+ set(spdx_v23_json_require_help_string
+ "Error out if JSON SBOM generation depdendency is not found.")
+
+ set(spdx_v23_verify_help_string
+ "Verify generated SBOM documents using python spdx-tools package.")
- option(QT_SBOM_VERIFY "Verify generated SBOM documents using python spdx-tools package." ON)
- option(QT_SBOM_REQUIRE_VERIFY
- "Error out if SBOM verification dependencies are not found." OFF)
+ set(spdx_v23_verify_require_help_string
+ "Error out if SBOM verification dependencies are not found.")
+
+ option(QT_SBOM_GENERATE_SPDX_V2_JSON "${spdx_v23_json_help_string}" ON)
+ option(QT_SBOM_REQUIRE_GENERATE_SPDX_V2_JSON "${spdx_v23_json_require_help_string}" OFF)
+
+ option(QT_SBOM_VERIFY_SPDX_V2 "${spdx_v23_verify_help_string}" ON)
+ option(QT_SBOM_REQUIRE_VERIFY_SPDX_V2 "${spdx_v23_verify_require_help_string}" OFF)
+
+
+ # Options for CycloneDX verification and verbosity.
+
+ set(cydx_verify_help_string
+ "Verify generated CycloneDX document against its json schema.")
+ option(QT_SBOM_VERIFY_CYDX_V1_6 "${cydx_verify_help_string}" ON)
+
+ set(cydx_verify_require_help_string
+ "Error out if SBOM verification dependencies are not found.")
+ option(QT_SBOM_REQUIRE_VERIFY_CYDX_V1_6 "${cydx_verify_require_help_string}" OFF)
+
+ set(cydx_verbose_help_string
+ "Enable verbose output for CycloneDX generation.")
+ option(QT_SBOM_VERBOSE_CYDX_V1_6 "${cydx_verbose_help_string}" OFF)
+
+
+ # Deprecated options, superseded by the options above.
+ # Only add them if the values was previously defined, but update the doc string.
+
+ if(DEFINED QT_SBOM_GENERATE_JSON)
+ option(QT_SBOM_GENERATE_JSON "Deprecated: ${spdx_v23_json_help_string}" ON)
+ endif()
+ if(DEFINED QT_SBOM_REQUIRE_GENERATE_JSON)
+ option(QT_SBOM_REQUIRE_GENERATE_JSON "Deprecated: ${spdx_v23_json_require_help_string}" OFF)
+ endif()
+ if(DEFINED QT_SBOM_VERIFY)
+ option(QT_SBOM_VERIFY "Deprecated: ${spdx_v23_verify_help_string}" ON)
+ endif()
+ if(DEFINED QT_SBOM_REQUIRE_VERIFY)
+ option(QT_SBOM_REQUIRE_VERIFY "Deprecated: ${spdx_v23_verify_require_help_string}" OFF)
+ endif()
+
+ # Semi-public, undocumented options to allow enabling all SBOM stuff, for easier testing.
+ if(QT_SBOM_GENERATE_AND_VERIFY_ALL)
+ set(QT_SBOM_GENERATE_ALL ON)
+ set(QT_SBOM_GENERATE_REQUIRED_ALL ON)
+ set(QT_SBOM_VERIFY_REQUIRED_ALL ON)
+ endif()
+
+ if(QT_SBOM_GENERATE_ALL)
+ set(QT_GENERATE_SBOM ON CACHE BOOL "${sbom_help_string}" FORCE)
+ set(QT_SBOM_GENERATE_SPDX_V2 ON CACHE BOOL "${spdx_v2_help_string}" FORCE)
+ set(QT_SBOM_GENERATE_SPDX_V2_JSON ON CACHE BOOL "${spdx_v23_json_help_string}" FORCE)
+ set(QT_SBOM_GENERATE_CYDX_V1_6 ON CACHE BOOL "${cydx_help_string}" FORCE)
+ unset(QT_SBOM_GENERATE_ALL CACHE)
+ unset(QT_SBOM_GENERATE_ALL)
+ endif()
+
+ if(QT_SBOM_GENERATE_REQUIRED_ALL)
+ set(QT_SBOM_REQUIRE_GENERATE_SPDX_V2_JSON ON CACHE BOOL
+ "${spdx_v23_json_require_help_string}" FORCE)
+ set(QT_SBOM_REQUIRE_GENERATE_CYDX_V1_6 ON CACHE BOOL "${cydx_require_help_string}" FORCE)
+
+ unset(QT_SBOM_GENERATE_REQUIRED_ALL CACHE)
+ unset(QT_SBOM_GENERATE_REQUIRED_ALL)
+ endif()
+
+ if(QT_SBOM_VERIFY_REQUIRED_ALL)
+ set(QT_SBOM_VERIFY_SPDX_V2 ON CACHE BOOL "${spdx_v23_verify_help_string}" FORCE)
+ set(QT_SBOM_VERIFY_CYDX_V1_6 ON CACHE BOOL "${cydx_verify_help_string}" FORCE)
+
+ set(QT_SBOM_REQUIRE_VERIFY_SPDX_V2 ON CACHE BOOL "${spdx_v23_verify_require_help_string}"
+ FORCE)
+ set(QT_SBOM_REQUIRE_VERIFY_CYDX_V1_6 ON CACHE BOOL "${cydx_verify_require_help_string}"
+ FORCE)
+
+ unset(QT_SBOM_VERIFY_ALL CACHE)
+ unset(QT_SBOM_VERIFY_ALL)
+ endif()
+
+ # Various sanity checks.
+
+ # Disable SPDX v2.3 JSON generation if tag:value generation is disabled.
+ if(QT_GENERATE_SBOM
+ AND QT_SBOM_GENERATE_SPDX_V2_JSON
+ AND NOT QT_SBOM_GENERATE_SPDX_V2)
+ if(NOT QT_NO_SBOM_INFORMATIONAL_MESSAGES)
+ message(STATUS
+ "Disabling SPDX v2.3 SBOM JSON generation because tag:value generation is "
+ "disabled and that is a requirement for JSON generation.")
+ endif()
+ set(QT_SBOM_GENERATE_SPDX_V2_JSON OFF CACHE BOOL "${spdx_v23_json_help_string}" FORCE)
+ set(QT_SBOM_VERIFY_SPDX_V2 OFF CACHE BOOL "${spdx_v23_verify_help_string}" FORCE)
+ endif()
+
+ # Disable CycloneDX generation if dependencies are not found and it wasn't required.
+ if(QT_GENERATE_SBOM
+ AND QT_SBOM_GENERATE_CYDX_V1_6
+ AND NOT QT_SBOM_REQUIRE_GENERATE_CYDX_V1_6)
+ _qt_internal_sbom_find_cydx_dependencies(OUT_VAR_DEPS_FOUND deps_found)
+ if(NOT deps_found)
+ if(NOT QT_NO_SBOM_INFORMATIONAL_MESSAGES)
+ message(STATUS
+ "Disabling Cyclone DX SBOM generation because dependencies were not found, "
+ "and generation was not marked as required.")
+ endif()
+ set(QT_SBOM_GENERATE_CYDX_V1_6 OFF CACHE BOOL "${cydx_help_string}" FORCE)
+ endif()
+ endif()
+
+ # Disable sbom generation if none of the formats are enabled. Failing to do so will cause
+ # errors in _qt_internal_sbom_begin_project.
+ if(QT_GENERATE_SBOM
+ AND NOT QT_SBOM_GENERATE_SPDX_V2
+ AND NOT QT_SBOM_GENERATE_CYDX_V1_6)
+ if(NOT QT_NO_SBOM_INFORMATIONAL_MESSAGES)
+ message(STATUS
+ "Disabling SBOM generation because none of the supported formats were enabled.")
+ endif()
+ set(QT_GENERATE_SBOM OFF CACHE BOOL "${sbom_help_string}" FORCE)
+ endif()
endfunction()
# Ends repo sbom project generation.
@@ -415,10 +636,6 @@ function(_qt_internal_sbom_end_project)
return()
endif()
- # Now that we know which system libraries are linked against because we added all
- # subdirectories, we can add the recorded system libs to the sbom.
- _qt_internal_sbom_add_recorded_system_libraries()
-
# Run sbom finalization for targets that had it scheduled, but haven't run yet.
# This can happen when _qt_internal_sbom_end_project is called within the same
# subdirectory scope as where the targets are meant to be finalized, but that would be too late
@@ -462,7 +679,24 @@ function(_qt_internal_sbom_end_project)
endif()
endwhile()
- _qt_internal_sbom_end_project_generate()
+ # Now that we know which system libraries are linked against because we added all
+ # subdirectories and finalized all targets, we can add the recorded system libs to the sbom.
+ _qt_internal_sbom_add_recorded_system_libraries()
+
+ # Add any external target dependencies, for CycloneDX generation.
+ # E.g. For QtSvg, we need to create a QtCore component in the QtSvg document, so that we
+ # can declare a dependency on it.
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ _qt_internal_sbom_add_cydx_external_target_dependencies()
+ endif()
+
+ if(QT_SBOM_GENERATE_SPDX_V2)
+ _qt_internal_sbom_end_project_generate()
+ endif()
+
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ _qt_internal_sbom_end_project_generate_cyclone()
+ endif()
# Clean up external document ref properties, because each repo needs to start from scratch
# in a top-level build.
@@ -777,7 +1011,8 @@ function(_qt_internal_sbom_add_target target)
set_target_properties(${target} PROPERTIES _qt_sbom_is_qt_module TRUE)
endif()
- set(project_package_options "")
+ set(project_package_options_spdx "")
+ set(project_package_options_cydx "")
if(arg_FRIENDLY_PACKAGE_NAME)
set(package_name_for_spdx_id "${arg_FRIENDLY_PACKAGE_NAME}")
@@ -887,7 +1122,8 @@ function(_qt_internal_sbom_add_target target)
endif()
if(license_expression)
- list(APPEND project_package_options LICENSE_CONCLUDED "${license_expression}")
+ list(APPEND project_package_options_spdx LICENSE_CONCLUDED "${license_expression}")
+ list(APPEND project_package_options_cydx LICENSE_CONCLUDED "${license_expression}")
endif()
if(license_expression AND
@@ -898,7 +1134,9 @@ function(_qt_internal_sbom_add_target target)
LICENSE_CONCLUDED_EXPRESSION "${license_expression}"
OUT_VAR qt_entity_license_declared_expression)
if(qt_entity_license_declared_expression)
- list(APPEND project_package_options
+ list(APPEND project_package_options_spdx
+ LICENSE_DECLARED "${qt_entity_license_declared_expression}")
+ list(APPEND project_package_options_cydx
LICENSE_DECLARED "${qt_entity_license_declared_expression}")
endif()
endif()
@@ -923,7 +1161,8 @@ function(_qt_internal_sbom_add_target target)
endif()
if(copyrights)
list(JOIN copyrights "\n" copyrights)
- list(APPEND project_package_options COPYRIGHT "<text>${copyrights}</text>")
+ list(APPEND project_package_options_spdx COPYRIGHT "<text>${copyrights}</text>")
+ list(APPEND project_package_options_cydx COPYRIGHT "${copyrights}")
endif()
set(package_version "")
@@ -943,7 +1182,12 @@ function(_qt_internal_sbom_add_target target)
endif()
if(package_version)
- list(APPEND project_package_options VERSION "${package_version}")
+ list(APPEND project_package_options_spdx VERSION "${package_version}")
+ list(APPEND project_package_options_cydx VERSION "${package_version}")
+
+ # Also export the value in a target property, to make it available for cydx generation.
+ set_property(TARGET "${target}" PROPERTY _qt_sbom_package_version "${package_version}")
+ set_property(TARGET "${target}" APPEND PROPERTY EXPORT_PROPERTIES _qt_sbom_package_version)
endif()
set(supplier "")
@@ -961,7 +1205,8 @@ function(_qt_internal_sbom_add_target target)
endif()
if(supplier)
- list(APPEND project_package_options SUPPLIER "Organization: ${supplier}")
+ list(APPEND project_package_options_spdx SUPPLIER "Organization: ${supplier}")
+ list(APPEND project_package_options_cydx CYDX_SUPPLIER "${supplier}")
endif()
set(download_location "")
@@ -1002,11 +1247,12 @@ function(_qt_internal_sbom_add_target target)
endif()
if(download_location)
- list(APPEND project_package_options DOWNLOAD_LOCATION "${download_location}")
+ list(APPEND project_package_options_spdx DOWNLOAD_LOCATION "${download_location}")
+ list(APPEND project_package_options_cydx DOWNLOAD_LOCATION "${download_location}")
endif()
_qt_internal_sbom_get_package_purpose("${sbom_entity_type}" package_purpose)
- list(APPEND project_package_options PURPOSE "${package_purpose}")
+ list(APPEND project_package_options_spdx PURPOSE "${package_purpose}")
set(cpe_values "")
@@ -1046,7 +1292,8 @@ function(_qt_internal_sbom_add_target target)
endif()
if(cpe_values)
- list(APPEND project_package_options CPE ${cpe_values})
+ list(APPEND project_package_options_spdx CPE ${cpe_values})
+ list(APPEND project_package_options_cydx CPE ${cpe_values})
endif()
# Assemble arguments to forward to the function that handles purl options.
@@ -1088,12 +1335,16 @@ function(_qt_internal_sbom_add_target target)
list(APPEND purl_args PURL_VALUES ${qa_purls_replaced})
endif()
- list(APPEND purl_args OUT_VAR purl_package_options)
+ list(APPEND purl_args
+ OUT_VAR_PURL_VALUES purl_values
+ OUT_VAR_SPDX_EXT_REF_VALUES spdx_ext_ref_values
+ )
_qt_internal_sbom_handle_purl_values(${target} ${purl_args})
- if(purl_package_options)
- list(APPEND project_package_options ${purl_package_options})
+ if(spdx_ext_ref_values)
+ list(APPEND project_package_options_spdx ${spdx_ext_ref_values})
+ list(APPEND project_package_options_cydx PURL_VALUES ${purl_values})
endif()
if(arg_USE_ATTRIBUTION_FILES)
@@ -1136,32 +1387,75 @@ function(_qt_internal_sbom_add_target target)
endif()
if(package_comment)
- list(APPEND project_package_options COMMENT "<text>\n${package_comment}</text>")
+ list(APPEND project_package_options_spdx COMMENT "<text>\n${package_comment}</text>")
+ list(APPEND project_package_options_cydx COMMENT "\n${package_comment}")
endif()
_qt_internal_sbom_handle_target_dependencies("${target}"
SPDX_ID "${package_spdx_id}"
LIBRARIES "${arg_LIBRARIES}"
PUBLIC_LIBRARIES "${arg_PUBLIC_LIBRARIES}"
- OUT_RELATIONSHIPS relationships
+ OUT_CYDX_DEPENDENCIES cydx_dependencies
+ OUT_SPDX_RELATIONSHIPS spdx_relationships
+ OUT_EXTERNAL_TARGET_DEPENDENCIES external_target_dependencies
)
+ if(cydx_dependencies)
+ list(APPEND project_package_options_cydx DEPENDENCIES ${cydx_dependencies})
+ endif()
+
+ # These are processed at the end of document generation.
+ if(external_target_dependencies)
+ _qt_internal_sbom_record_external_target_dependecies(
+ TARGETS ${external_target_dependencies}
+ )
+ endif()
get_cmake_property(project_spdx_id _qt_internal_sbom_project_spdx_id)
- list(APPEND relationships "${project_spdx_id} CONTAINS ${package_spdx_id}")
+ list(APPEND spdx_relationships "${project_spdx_id} CONTAINS ${package_spdx_id}")
if(arg_SBOM_RELATIONSHIPS)
- list(APPEND relationships "${arg_SBOM_RELATIONSHIPS}")
+ list(APPEND spdx_relationships "${arg_SBOM_RELATIONSHIPS}")
endif()
- list(REMOVE_DUPLICATES relationships)
- list(JOIN relationships "\nRelationship: " relationships)
- list(APPEND project_package_options RELATIONSHIP "${relationships}")
+ list(REMOVE_DUPLICATES spdx_relationships)
+ list(JOIN spdx_relationships "\nRelationship: " relationships)
+ list(APPEND project_package_options_spdx RELATIONSHIP "${relationships}")
- _qt_internal_sbom_generate_add_package(
- PACKAGE "${package_name_for_spdx_id}"
- SPDXID "${package_spdx_id}"
- ${project_package_options}
- )
+ if(QT_SBOM_GENERATE_SPDX_V2)
+ _qt_internal_sbom_generate_add_package(
+ PACKAGE "${package_name_for_spdx_id}"
+ SPDXID "${package_spdx_id}"
+ ${project_package_options_spdx}
+ )
+ endif()
+
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ get_property(external_targets
+ GLOBAL PROPERTY _qt_internal_sbom_external_target_dependencies)
+
+ # Prevent against case when a system library is also an external target dependency,
+ # which would lead to its creation twice, once via
+ # _qt_internal_sbom_add_recorded_system_libraries
+ # and second time via
+ # _qt_internal_sbom_add_cydx_external_target_dependencies.
+ # Skip the case when it's done via the first function, and only allow the second.
+ # TODO: Can this be done better somehow?
+ if(NOT target IN_LIST external_targets)
+ _qt_internal_sbom_handle_qt_entity_cydx_properties(
+ SBOM_ENTITY_TYPE "${sbom_entity_type}"
+ OUT_CYDX_PROPERTIES cydx_properties
+ )
+
+ _qt_internal_sbom_generate_cyclone_add_package(
+ PACKAGE "${package_name_for_spdx_id}"
+ SPDXID "${package_spdx_id}"
+ SBOM_ENTITY_TYPE "${sbom_entity_type}"
+ ${project_package_options_cydx}
+ CONTAINING_COMPONENT "${project_spdx_id}"
+ CYDX_PROPERTIES ${cydx_properties}
+ )
+ endif()
+ endif()
set(no_install_option "")
if(arg_NO_INSTALL)
@@ -1199,25 +1493,27 @@ function(_qt_internal_sbom_add_target target)
set(license_option LICENSE_EXPRESSION "${license_expression}")
endif()
- _qt_internal_sbom_handle_target_binary_files("${target}"
- ${no_install_option}
- ${framework_option}
- ${install_prefix_option}
- SBOM_ENTITY_TYPE "${sbom_entity_type}"
- ${target_binary_multi_config_args}
- SPDX_ID "${package_spdx_id}"
- ${copyrights_option}
- ${license_option}
- )
+ if(QT_SBOM_GENERATE_SPDX_V2)
+ _qt_internal_sbom_handle_target_binary_files("${target}"
+ ${no_install_option}
+ ${framework_option}
+ ${install_prefix_option}
+ SBOM_ENTITY_TYPE "${sbom_entity_type}"
+ ${target_binary_multi_config_args}
+ SPDX_ID "${package_spdx_id}"
+ ${copyrights_option}
+ ${license_option}
+ )
- _qt_internal_sbom_handle_target_custom_files("${target}"
- ${no_install_option}
- ${install_prefix_option}
- PACKAGE_TYPE "${sbom_entity_type}"
- PACKAGE_SPDX_ID "${package_spdx_id}"
- ${copyrights_option}
- ${license_option}
- )
+ _qt_internal_sbom_handle_target_custom_files("${target}"
+ ${no_install_option}
+ ${install_prefix_option}
+ PACKAGE_TYPE "${sbom_entity_type}"
+ PACKAGE_SPDX_ID "${package_spdx_id}"
+ ${copyrights_option}
+ ${license_option}
+ )
+ endif()
endfunction()
# Helper to add sbom information for a possibly non-existing target.
@@ -1576,7 +1872,11 @@ function(_qt_internal_sbom_record_target_spdx_id target)
SBOM_ENTITY_TYPE "${arg_SBOM_ENTITY_TYPE}"
PACKAGE_NAME "${package_name_for_spdx_id}"
)
- _qt_internal_sbom_save_spdx_id_for_target("${target}" "${package_spdx_id}")
+ _qt_internal_sbom_save_spdx_id_for_target("${target}"
+ SPDX_ID "${package_spdx_id}"
+ PACKAGE_NAME "${package_name_for_spdx_id}"
+ SBOM_ENTITY_TYPE "${arg_SBOM_ENTITY_TYPE}"
+ )
_qt_internal_sbom_is_qt_entity_type("${arg_SBOM_ENTITY_TYPE}" is_qt_entity_type)
_qt_internal_sbom_save_spdx_id_for_qt_entity_type(
@@ -1615,10 +1915,36 @@ function(_qt_internal_sbom_generate_target_package_spdx_id out_var)
endfunction()
# Save a spdx id for a target inside its target properties.
-# Also saves the repo document namespace and relative installed repo document path.
# These are used when generating a SPDX external document reference for exported targets, to
# include them in relationships.
-function(_qt_internal_sbom_save_spdx_id_for_target target spdx_id)
+# Also saves the repo document namespace and relative installed repo document path.
+# Also saves the sbom entity type and package name, because it's needed when creating CycloneDX
+# components where the target is in an external document.
+function(_qt_internal_sbom_save_spdx_id_for_target target)
+ set(opt_args "")
+ set(single_args
+ SPDX_ID
+ PACKAGE_NAME
+ SBOM_ENTITY_TYPE
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ if(NOT arg_SPDX_ID)
+ message(FATAL_ERROR "arg_SPDX_ID must be set")
+ endif()
+
+ if(NOT arg_PACKAGE_NAME)
+ message(FATAL_ERROR "PACKAGE_NAME must be set")
+ endif()
+
+ if(NOT arg_SBOM_ENTITY_TYPE)
+ message(FATAL_ERROR "SBOM_ENTITY_TYPE must be set")
+ endif()
+
+ set(spdx_id "${arg_SPDX_ID}")
+
message(DEBUG "Saving spdx id for target ${target}: ${spdx_id}")
set(target_unaliased "${target}")
@@ -1631,6 +1957,9 @@ function(_qt_internal_sbom_save_spdx_id_for_target target spdx_id)
get_property(repo_document_namespace
GLOBAL PROPERTY _qt_internal_sbom_repo_document_namespace)
+ get_property(bom_serial_number_uuid
+ GLOBAL PROPERTY _qt_internal_sbom_repo_cyclone_dx_bom_serial_number_uuid)
+
get_property(relative_installed_repo_document_path
GLOBAL PROPERTY _qt_internal_sbom_relative_installed_repo_document_path)
@@ -1643,6 +1972,10 @@ function(_qt_internal_sbom_save_spdx_id_for_target target spdx_id)
"${repo_document_namespace}")
set_property(TARGET ${target_unaliased} PROPERTY
+ _qt_sbom_cydx_bom_serial_number_uuid
+ "${bom_serial_number_uuid}")
+
+ set_property(TARGET ${target_unaliased} PROPERTY
_qt_sbom_spdx_relative_installed_repo_document_path
"${relative_installed_repo_document_path}")
@@ -1650,11 +1983,22 @@ function(_qt_internal_sbom_save_spdx_id_for_target target spdx_id)
_qt_sbom_spdx_repo_project_name_lowercase
"${project_name_lowercase}")
+ set_property(TARGET ${target_unaliased} PROPERTY
+ _qt_sbom_package_name
+ "${arg_PACKAGE_NAME}")
+
+ set_property(TARGET ${target_unaliased} PROPERTY
+ _qt_sbom_entity_type
+ "${arg_SBOM_ENTITY_TYPE}")
+
# Export the properties, so they can be queried by other repos.
# We also do it for versionless targets.
set(export_properties
+ _qt_sbom_entity_type
+ _qt_sbom_package_name
_qt_sbom_spdx_id
_qt_sbom_spdx_repo_document_namespace
+ _qt_sbom_cydx_bom_serial_number_uuid
_qt_sbom_spdx_relative_installed_repo_document_path
_qt_sbom_spdx_repo_project_name_lowercase
)
@@ -1719,11 +2063,18 @@ function(_qt_internal_sbom_save_spdx_id_for_qt_entity_type target is_qt_entity_t
versionless_target
versionless_private_target
)
+
+ get_property(package_name TARGET "${target}" PROPERTY _qt_sbom_package_name)
+ get_property(sbom_entity_type TARGET "${target}" PROPERTY _qt_sbom_entity_type)
endif()
foreach(target_name IN LISTS ${target_names})
if(TARGET "${target_name}")
- _qt_internal_sbom_save_spdx_id_for_target("${target_name}" "${package_spdx_id}")
+ _qt_internal_sbom_save_spdx_id_for_target("${target_name}"
+ SPDX_ID "${package_spdx_id}"
+ PACKAGE_NAME "${package_name}"
+ SBOM_ENTITY_TYPE "${sbom_entity_type}"
+ )
endif()
endforeach()
endfunction()
@@ -2025,7 +2376,12 @@ endfunction()
function(_qt_internal_sbom_compute_project_file_name out_var)
set(opt_args
- EXTENSION_JSON
+ SPDX_TAG_VALUE
+ SPDX_JSON
+ CYCLONEDX_JSON
+ CYCLONEDX_TOML
+
+ EXTENSION_JSON # deprecated, used by WebEngine
)
set(single_args
PROJECT_NAME
@@ -2040,6 +2396,16 @@ function(_qt_internal_sbom_compute_project_file_name out_var)
message(FATAL_ERROR "PROJECT_NAME must be set")
endif()
+ if(NOT arg_SPDX_JSON
+ AND NOT arg_SPDX_TAG_VALUE
+ AND NOT arg_CYCLONEDX_TOML
+ AND NOT arg_CYCLONEDX_JSON
+ AND NOT arg_EXTENSION_JSON
+ )
+ message(FATAL_ERROR "One of the following options should be set: "
+ "SPDX_TAG_VALUE, SPDX_JSON, CYCLONEDX_JSON, CYCLONEDX_TOML")
+ endif()
+
string(TOLOWER "${arg_PROJECT_NAME}" project_name_lowercase)
set(version_suffix "")
@@ -2050,10 +2416,16 @@ function(_qt_internal_sbom_compute_project_file_name out_var)
set(version_suffix "-${QT_REPO_MODULE_VERSION}")
endif()
- if(arg_EXTENSION_JSON)
+ if(arg_SPDX_TAG_VALUE)
+ set(extension "spdx")
+ elseif(arg_SPDX_JSON OR arg_EXTENSION_JSON)
set(extension "spdx.json")
+ elseif(arg_CYCLONEDX_TOML)
+ set(extension "cdx.toml")
+ elseif(arg_CYCLONEDX_JSON)
+ set(extension "cdx.json")
else()
- set(extension "spdx")
+ message(FATAL_ERROR "Unknown file extension for SBOM generation.")
endif()
set(result
diff --git a/cmake/QtPublicSbomLicenseHelpers.cmake b/cmake/QtPublicSbomLicenseHelpers.cmake
index a91f4c2cefa..a9529fbe3d7 100644
--- a/cmake/QtPublicSbomLicenseHelpers.cmake
+++ b/cmake/QtPublicSbomLicenseHelpers.cmake
@@ -44,10 +44,20 @@ function(_qt_internal_sbom_add_license)
set(license_id "LicenseRef-${license_id}")
endif()
- _qt_internal_sbom_generate_add_license(
- LICENSE_ID "${license_id}"
- EXTRACTED_TEXT "<text>${text}</text>"
- )
+
+ if(QT_SBOM_GENERATE_SPDX_V2)
+ _qt_internal_sbom_generate_add_license(
+ LICENSE_ID "${license_id}"
+ EXTRACTED_TEXT "<text>${text}</text>"
+ )
+ endif()
+
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ _qt_internal_sbom_record_license_cydx(
+ LICENSE_ID "${license_id}"
+ EXTRACTED_TEXT "${text}"
+ )
+ endif()
endfunction()
# Get a qt spdx license expression given the id.
diff --git a/cmake/QtPublicSbomOpsHelpers.cmake b/cmake/QtPublicSbomOpsHelpers.cmake
index 58af2a57f1f..78c4eaaa5e6 100644
--- a/cmake/QtPublicSbomOpsHelpers.cmake
+++ b/cmake/QtPublicSbomOpsHelpers.cmake
@@ -6,14 +6,28 @@
# like NTIA validation, auditing, json generation, etc.
function(_qt_internal_sbom_setup_project_ops_generation)
set(opt_args
+ # spdx options
GENERATE_JSON
GENERATE_JSON_REQUIRED
+
+ # cydx options
+ GENERATE_CYCLONE_DX_V1_6
+ GENERATE_CYCLONE_DX_V1_6_REQUIRED
+ VERIFY_CYCLONE_DX_V1_6
+ VERIFY_CYCLONE_DX_V1_6_REQUIRED
+ VERBOSE_CYCLONE_DX_V1_6
+
+ # source spdx options
GENERATE_SOURCE_SBOM
+ LINT_SOURCE_SBOM
+ LINT_SOURCE_SBOM_NO_ERROR
+
+ # Extra spdx verification
VERIFY_SBOM
VERIFY_SBOM_REQUIRED
VERIFY_NTIA_COMPLIANT
- LINT_SOURCE_SBOM
- LINT_SOURCE_SBOM_NO_ERROR
+
+ # Extra spdx info
SHOW_TABLE
AUDIT
AUDIT_NO_ERROR
@@ -38,6 +52,33 @@ function(_qt_internal_sbom_setup_project_ops_generation)
endif()
endif()
+ if(arg_GENERATE_CYCLONE_DX_V1_6 AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
+ set(op_args
+ OUT_VAR_DEPS_FOUND deps_found
+ )
+ if(arg_GENERATE_CYCLONE_DX_V1_6_REQUIRED)
+ list(APPEND op_args REQUIRED)
+ endif()
+
+ set(gen_args "")
+ if(arg_VERIFY_CYCLONE_DX_V1_6)
+ list(APPEND gen_args VERIFY)
+ endif()
+
+ if(arg_VERIFY_CYCLONE_DX_V1_6_REQUIRED)
+ list(APPEND gen_args VERIFY_REQUIRED)
+ endif()
+
+ if(arg_VERBOSE_CYCLONE_DX_V1_6)
+ list(APPEND gen_args VERBOSE)
+ endif()
+
+ _qt_internal_sbom_find_cydx_dependencies(${op_args})
+ if(deps_found)
+ _qt_internal_sbom_generate_cydx_json(${gen_args})
+ endif()
+ endif()
+
if(arg_VERIFY_SBOM AND NOT QT_INTERNAL_NO_SBOM_PYTHON_OPS)
set(op_args
OP_KEY "VERIFY_SBOM"
@@ -90,12 +131,119 @@ function(_qt_internal_sbom_setup_project_ops_generation)
endif()
endfunction()
+# Tries to find the dependencies for generating CycloneDX v1.6 SBOMs.
+# Sets OUT_VAR_DEPS_FOUND to TRUE if found, FALSE otherwise.
+function(_qt_internal_sbom_find_cydx_dependencies)
+ set(opt_args
+ REQUIRED
+ )
+ set(single_args
+ OUT_VAR_DEPS_FOUND
+ )
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+
+ if(NOT arg_OUT_VAR_DEPS_FOUND)
+ message(FATAL_ERROR "OUT_VAR_DEPS_FOUND is required")
+ endif()
+
+ set(op_args
+ OP_KEY "GENERATE_CYCLONE_DX_V1_6"
+ OUT_VAR_DEPS_FOUND deps_found
+ )
+
+ if(arg_REQUIRED)
+ list(APPEND op_args REQUIRED)
+ endif()
+
+ _qt_internal_sbom_find_and_handle_sbom_op_dependencies(${op_args})
+
+ set(${arg_OUT_VAR_DEPS_FOUND} "${deps_found}" PARENT_SCOPE)
+endfunction()
+
+# Helper to output a debug or error message when python or one of its dependencies are not found.
+# When found, it also caches the found python interpreter path and version, as well as the
+# DEPS_FOUND_FOR_$OP_KEY var.
+function(_qt_internal_sbom_verify_if_sbom_op_dependencies_are_found)
+ set(opt_args
+ REQUIRED
+ PYTHON_FOUND
+ DEP_FOUND
+ EVERYTHING_FOUND
+ )
+ set(single_args
+ REQUIRED_VERSION
+ PYTHON_PATH
+ PYTHON_VERSION
+ DEP_PACKAGE_NAME
+ DEP_FIND_OUTPUT
+ OP_KEY
+ )
+ set(multi_args
+ PYTHON_COMMON_ARGS
+ )
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+
+ if(arg_EVERYTHING_FOUND)
+ message(DEBUG "Python Dependencies found. "
+ "Using Python '${arg_PYTHON_PATH}' for running SBOM op '${arg_OP_KEY}'.")
+
+ if(NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
+ message(DEBUG "Setting QT_INTERNAL_SBOM_PYTHON_EXECUTABLE to ${arg_PYTHON_PATH}")
+ message(DEBUG "Setting QT_INTERNAL_SBOM_PYTHON_VERSION to ${arg_PYTHON_VERSION}")
+ set(QT_INTERNAL_SBOM_PYTHON_EXECUTABLE "${arg_PYTHON_PATH}" CACHE INTERNAL
+ "Python interpeter used for SBOM generation.")
+ set(QT_INTERNAL_SBOM_PYTHON_VERSION "${arg_PYTHON_VERSION}" CACHE INTERNAL
+ "Python interpeter version used for SBOM generation.")
+ endif()
+
+ set(QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${arg_OP_KEY} "TRUE" CACHE INTERNAL
+ "All dependencies found to run SBOM op '${arg_OP_KEY}'")
+ return()
+ endif()
+
+ if(arg_REQUIRED)
+ set(message_type "FATAL_ERROR")
+ else()
+ set(message_type "DEBUG")
+ endif()
+
+ if(NOT arg_PYTHON_FOUND)
+ # Look for python one more time, this time without QUIET, to show an error why it
+ # wasn't found.
+ if(arg_REQUIRED)
+ _qt_internal_sbom_find_python_helper(${arg_PYTHON_COMMON_ARGS}
+ OUT_VAR_PYTHON_PATH unused_python
+ OUT_VAR_PYTHON_FOUND unused_found
+ )
+ endif()
+ message(${message_type}
+ "Python ${arg_REQUIRED_VERSION} for running SBOM op '${arg_OP_KEY}' NOT found.")
+ elseif(NOT arg_DEP_FOUND)
+
+ set(extra_install_message "")
+ if(message_type STREQUAL "FATAL_ERROR")
+ set(extra_install_message
+ "Install it using pip install '${arg_DEP_PACKAGE_NAME}' \n")
+ endif()
+ message(${message_type}
+ "Python dependency for running SBOM op '${arg_OP_KEY}' NOT found:\n"
+ ${extra_install_message}
+ "Details:\n"
+ "Python interpreter: ${arg_PYTHON_PATH}\n"
+ "Error output: \n${arg_DEP_FIND_OUTPUT}\n\n"
+ )
+ endif()
+endfunction()
+
# Helper to find a python interpreter and a specific python dependency, e.g. to be able to generate
# a SPDX JSON SBOM, or run post-installation steps like NTIA verification.
# The exact dependency should be specified as the OP_KEY.
#
# Caches the found python executable in a separate cache var QT_INTERNAL_SBOM_PYTHON_EXECUTABLE, to
# avoid conflicts with any other found python interpreter.
+# Also caches the python version found in QT_INTERNAL_SBOM_PYTHON_VERSION, so we can show it
+# in the configure summary.
function(_qt_internal_sbom_find_and_handle_sbom_op_dependencies)
set(opt_args
REQUIRED
@@ -112,12 +260,22 @@ function(_qt_internal_sbom_find_and_handle_sbom_op_dependencies)
message(FATAL_ERROR "OP_KEY is required")
endif()
- set(supported_ops "GENERATE_JSON" "VERIFY_SBOM" "RUN_NTIA")
+ set(supported_ops
+ "GENERATE_JSON"
+ "GENERATE_CYCLONE_DX_V1_6"
+ "VERIFY_SBOM"
+ "RUN_NTIA"
+ )
if(arg_OP_KEY STREQUAL "GENERATE_JSON" OR arg_OP_KEY STREQUAL "VERIFY_SBOM")
set(import_statement "import spdx_tools.spdx.clitools.pyspdxtools")
+ set(dep_package_name "spdx-tools")
+ elseif(arg_OP_KEY STREQUAL "GENERATE_CYCLONE_DX_V1_6")
+ set(import_statement "from cyclonedx.output.json import JsonV1Dot6")
+ set(dep_package_name "cyclonedx-python-lib[json-validation]")
elseif(arg_OP_KEY STREQUAL "RUN_NTIA")
set(import_statement "import ntia_conformance_checker.main")
+ set(dep_package_name "ntia-conformance-checker")
else()
message(FATAL_ERROR "OP_KEY must be one of ${supported_ops}")
endif()
@@ -145,48 +303,81 @@ function(_qt_internal_sbom_find_and_handle_sbom_op_dependencies)
# non-framework python found.
if(CMAKE_HOST_APPLE)
set(extra_python_args SEARCH_IN_FRAMEWORKS QUIET)
+ message(DEBUG "Looking for Python and dependencies for op '${arg_OP_KEY}' "
+ "in the system framework location first.")
_qt_internal_sbom_find_python_and_dependency_helper_lambda()
+ if(NOT everything_found)
+ # Assemble args to show what wasn't found.
+ set(verify_args "")
+ if(python_found)
+ list(APPEND verify_args PYTHON_FOUND)
+ endif()
+ if(dep_found)
+ list(APPEND verify_args DEP_FOUND)
+ endif()
+ if(everything_found)
+ list(APPEND verify_args EVERYTHING_FOUND)
+ endif()
+ if(python_path)
+ list(APPEND verify_args PYTHON_PATH "${python_path}")
+ endif()
+ if(python_version)
+ list(APPEND verify_args PYTHON_VERSION "${python_version}")
+ endif()
+ if(dep_find_output)
+ list(APPEND verify_args DEP_FIND_OUTPUT "${dep_find_output}")
+ endif()
+
+ _qt_internal_sbom_verify_if_sbom_op_dependencies_are_found(
+ ${verify_args}
+ REQUIRED_VERSION "${required_version}"
+ OP_KEY "${arg_OP_KEY}"
+ DEP_PACKAGE_NAME "${dep_package_name}"
+ PYTHON_COMMON_ARGS ${python_common_args}
+ )
+
+ message(DEBUG "Initial Apple-specific SBOM Python search did not find all dependencies "
+ "for op ${arg_OP_KEY}, looking again outside of the system framework location.")
+ endif()
endif()
+ # Looking again if something wasn't found, or a search was not done yet.
if(NOT everything_found)
set(extra_python_args QUIET)
+ message(DEBUG "Looking for Python and dependencies for op '${arg_OP_KEY}'.")
_qt_internal_sbom_find_python_and_dependency_helper_lambda()
endif()
- # Always save the python interpreter path if it is found, even if the dependencies are not
- # found. This improves the error message workflow.
- if(python_found AND NOT QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
- set(QT_INTERNAL_SBOM_PYTHON_EXECUTABLE "${python_path}" CACHE INTERNAL
- "Python interpeter used for SBOM generation.")
+ # Assemble args to show what was or wasn't found.
+ set(verify_args "")
+ if(arg_REQUIRED)
+ list(APPEND verify_args REQUIRED)
endif()
-
- if(NOT everything_found)
- if(arg_REQUIRED)
- set(message_type "FATAL_ERROR")
- else()
- set(message_type "DEBUG")
- endif()
-
- if(NOT python_found)
- # Look for python one more time, this time without QUIET, to show an error why it
- # wasn't found.
- if(arg_REQUIRED)
- _qt_internal_sbom_find_python_helper(${python_common_args}
- OUT_VAR_PYTHON_PATH unused_python
- OUT_VAR_PYTHON_FOUND unused_found
- )
- endif()
- message(${message_type} "Python ${required_version} for running SBOM ops not found.")
- elseif(NOT dep_found)
- message(${message_type} "Python dependency for running SBOM op ${arg_OP_KEY} "
- "not found:\n Python: ${python_path} \n Output: \n${dep_find_output}")
- endif()
- else()
- message(DEBUG "Using Python ${python_path} for running SBOM ops.")
-
- set(QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${arg_OP_KEY} "TRUE" CACHE INTERNAL
- "All dependencies found to run SBOM OP ${arg_OP_KEY}")
+ if(python_found)
+ list(APPEND verify_args PYTHON_FOUND)
+ endif()
+ if(dep_found)
+ list(APPEND verify_args DEP_FOUND)
+ endif()
+ if(everything_found)
+ list(APPEND verify_args EVERYTHING_FOUND)
+ endif()
+ if(python_path)
+ list(APPEND verify_args PYTHON_PATH "${python_path}")
endif()
+ if(python_version)
+ list(APPEND verify_args PYTHON_VERSION "${python_version}")
+ endif()
+ if(dep_find_output)
+ list(APPEND verify_args DEP_FIND_OUTPUT "${dep_find_output}")
+ endif()
+ _qt_internal_sbom_verify_if_sbom_op_dependencies_are_found(
+ ${verify_args}
+ REQUIRED_VERSION "${required_version}"
+ OP_KEY "${arg_OP_KEY}"
+ DEP_PACKAGE_NAME "${dep_package_name}"
+ PYTHON_COMMON_ARGS ${python_common_args}
+ )
if(arg_OUT_VAR_DEPS_FOUND)
set(${arg_OUT_VAR_DEPS_FOUND} "${QT_INTERNAL_SBOM_DEPS_FOUND_FOR_${arg_OP_KEY}}"
@@ -298,7 +489,7 @@ function(_qt_internal_sbom_check_python_dependency_available)
_qt_internal_validate_all_args_are_parsed(arg)
set(failure_message
- "Required Python dependencies not found: ")
+ "Required Python dependencies NOT found: ")
if(arg_FAILURE_MESSAGE_PREFIX)
list(PREPEND failure_message ${arg_FAILURE_MESSAGE_PREFIX})
@@ -393,6 +584,67 @@ function(_qt_internal_sbom_generate_json)
set_property(GLOBAL APPEND PROPERTY _qt_sbom_cmake_verify_include_files "${verify_sbom}")
endfunction()
+# Helper to generate a CycloneDX JSON file from the intermediate .toml file created by the build
+# system.
+function(_qt_internal_sbom_generate_cydx_json)
+ set(opt_args
+ VERIFY
+ VERIFY_REQUIRED
+ VERBOSE
+ )
+ set(single_args "")
+ set(multi_args "")
+ cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
+ _qt_internal_validate_all_args_are_parsed(arg)
+
+ set(error_message_prefix "Failed to generate a CycloneDX json file.")
+ _qt_internal_sbom_assert_python_interpreter_available("${error_message_prefix}")
+ _qt_internal_sbom_assert_python_dependency_available(GENERATE_CYCLONE_DX_V1_6
+ "cyclonedx" ${error_message_prefix})
+
+ _qt_internal_sbom_get_cyclone_dx_generator_path(generator_path)
+
+ set(extra_args "")
+ if(arg_VERIFY)
+ list(APPEND extra_args "--validate-json")
+ endif()
+ if(arg_VERIFY_REQUIRED)
+ list(APPEND extra_args "--validate-json-required")
+ endif()
+ if(arg_VERBOSE)
+ list(APPEND extra_args "--verbose")
+ endif()
+ list(JOIN extra_args " " extra_args)
+
+ set(content "
+ message(STATUS
+ \"Generating final CycloneDX JSON: \${QT_SBOM_OUTPUT_PATH_WITHOUT_EXT}.json\")
+ execute_process(
+ COMMAND \"${QT_INTERNAL_SBOM_PYTHON_EXECUTABLE}\" \"${generator_path}\"
+ --input-path \"\${QT_SBOM_OUTPUT_PATH}\"
+ --output-path \"\${QT_SBOM_OUTPUT_PATH_WITHOUT_EXT}.json\"
+ ${extra_args}
+ RESULT_VARIABLE res
+ )
+ if(NOT res EQUAL 0)
+ message(FATAL_ERROR \"CycloneDX JSON generation failed: \${res}\")
+ endif()
+ # Remove the intermediate toml file, there's no point in installing it.
+ # Keep the one in the build dir, it's useful for debugging.
+ if(NOT QT_SBOM_BUILD_TIME)
+ message(STATUS \"Removing intermediate TOML file \${QT_SBOM_OUTPUT_PATH}\")
+ file(REMOVE \"\${QT_SBOM_OUTPUT_PATH}\")
+ endif()
+")
+
+ _qt_internal_get_current_project_sbom_dir(sbom_dir)
+ set(generate_cydx "${sbom_dir}/generate_cyclone_dx.cmake")
+ file(GENERATE OUTPUT "${generate_cydx}" CONTENT "${content}")
+
+ set_property(GLOBAL APPEND PROPERTY
+ _qt_sbom_cmake_post_generation_include_files_cydx "${generate_cydx}")
+endfunction()
+
# Helper to query whether the all required dependencies are available to generate a tag / value
# document from a json one.
function(_qt_internal_sbom_verify_deps_for_generate_tag_value_spdx_document)
diff --git a/cmake/QtPublicSbomPurlHelpers.cmake b/cmake/QtPublicSbomPurlHelpers.cmake
index 6f91ea36fed..f6738a2431f 100644
--- a/cmake/QtPublicSbomPurlHelpers.cmake
+++ b/cmake/QtPublicSbomPurlHelpers.cmake
@@ -86,20 +86,31 @@ endmacro()
# default purls will be generated.
#
# There is no limit to the number of purls that can be added to a target.
+# The created purls are saved in:
+# - OUT_VAR_PURL_VALUES as plain purl values, to be used for CycloneDX genereation.
+# - OUT_VAR_SPDX_EXT_REF_VALUES as SPDX ExtRef entries, to be used for SPDX v2.3 generation.
function(_qt_internal_sbom_handle_purl_values target)
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
- list(APPEND single_args OUT_VAR)
+ list(APPEND single_args
+ OUT_VAR_SPDX_EXT_REF_VALUES
+ OUT_VAR_PURL_VALUES
+ )
cmake_parse_arguments(PARSE_ARGV 1 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
- if(NOT arg_OUT_VAR)
- message(FATAL_ERROR "OUT_VAR must be set")
+ if(NOT arg_OUT_VAR_PURL_VALUES)
+ message(FATAL_ERROR "OUT_VAR_PURL_VALUES must be set")
+ endif()
+
+ if(NOT arg_OUT_VAR_SPDX_EXT_REF_VALUES)
+ message(FATAL_ERROR "OUT_VAR_SPDX_EXT_REF_VALUES must be set")
endif()
_qt_internal_get_sbom_purl_parsing_options(purl_opt_args purl_single_args purl_multi_args)
- set(project_package_options "")
+ set(purl_values "")
+ set(spdx_ext_ref_values "")
# Collect each PURL_ENTRY args into a separate variable.
set(purl_idx -1)
@@ -140,6 +151,16 @@ function(_qt_internal_sbom_handle_purl_values target)
endif()
endif()
+ set(qt_entity_cydx_purl_values "")
+ set(qt_entity_spdx_purl_ext_refs "")
+
+ # When generating purls for Qt entities targeting Cyclone DX, we prefer the generic purl first,
+ # otherwise DependencyTrack gets confused with lots of components having the same purls,
+ # because it doesn't take into account the '#' part of the purl.
+ # Keep these separate and append them in the right order later.
+ set(qt_entity_cydx_purl_for_github_id "")
+ set(qt_entity_cydx_purl_for_generic_id "")
+
foreach(purl_idx IN LISTS purl_entry_indices)
# Clear previous values.
foreach(option_name IN LISTS purl_opt_args purl_single_args purl_multi_args)
@@ -172,11 +193,13 @@ function(_qt_internal_sbom_handle_purl_values target)
${purl_multi_args}
)
+ set(is_qt_entity_purl FALSE)
# Qt entity types get special treatment to gather the required args.
if(arg___QT_INTERNAL_HANDLE_QT_ENTITY_TYPE_PURL
AND arg_PURL_ID
AND arg_PURL_ID IN_LIST qt_purl_ids)
+ set(is_qt_entity_purl TRUE)
_qt_internal_sbom_handle_qt_entity_purl("${target}"
${purl_handling_args}
PURL_ID "${arg_PURL_ID}"
@@ -189,29 +212,57 @@ function(_qt_internal_sbom_handle_purl_values target)
_qt_internal_sbom_assemble_purl(${target}
${purl_args}
- OUT_VAR package_manager_external_ref
+ OUT_VAR purl_bare
+ OUT_VAR_SPDX_EXT_REF package_manager_external_ref_purl
)
- list(APPEND project_package_options ${package_manager_external_ref})
+
+ if(is_qt_entity_purl)
+ if(arg_PURL_ID STREQUAL "GENERIC")
+ set(qt_entity_cydx_purl_for_generic_id "${purl_bare}")
+ elseif(arg_PURL_ID STREQUAL "GITHUB")
+ set(qt_entity_cydx_purl_for_github_id "${purl_bare}")
+ else()
+ list(APPEND purl_values "${purl_bare}")
+ endif()
+ else()
+ list(APPEND purl_values "${purl_bare}")
+ endif()
+
+ list(APPEND spdx_ext_ref_values ${package_manager_external_ref_purl})
endforeach()
+ # Add the custom qt entity purls at the front in the right order for CycloneDX.
+ # If they are empty (for non-Qt entities), nothing will be prepended.
+ set(qt_entity_cydx_purl_values
+ ${qt_entity_cydx_purl_for_generic_id}
+ ${qt_entity_cydx_purl_for_github_id}
+ )
+ list(PREPEND purl_values ${qt_entity_cydx_purl_values})
+
foreach(purl_value IN LISTS arg_PURL_VALUES)
- _qt_internal_sbom_get_purl_value_extref(
- VALUE "${purl_value}" OUT_VAR package_manager_external_ref)
+ _qt_internal_sbom_get_purl_value_extref(VALUE "${purl_value}"
+ OUT_VAR package_manager_external_ref_purl)
# The order in which the purls are generated, matters for tools that consume the SBOM.
# Some tools can only handle one PURL per package, so the first one should be the
# important one.
# For now, I deem that the directly specified ones (probably via a qt_attribution.json
# file) are the more important ones. So we prepend them.
- list(PREPEND project_package_options ${package_manager_external_ref})
+ list(PREPEND purl_values ${purl_value})
+ list(PREPEND spdx_ext_ref_values ${package_manager_external_ref_purl})
endforeach()
- set(${arg_OUT_VAR} "${project_package_options}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_PURL_VALUES} "${purl_values}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_SPDX_EXT_REF_VALUES} "${spdx_ext_ref_values}" PARENT_SCOPE)
endfunction()
# Assembles an external reference purl identifier.
+#
# PURL_TYPE and PURL_NAME are required.
-# Stores the result in the OUT_VAR.
+#
+# Stores the bare purl in the OUT_VAR.
+# Stores the SPDX External Reference purl in the OUT_VAR_SPDX_EXT_REF.
+#
# Accepted options:
# PURL_TYPE
# PURL_NAME
@@ -223,6 +274,7 @@ function(_qt_internal_sbom_assemble_purl target)
set(opt_args "")
set(single_args
OUT_VAR
+ OUT_VAR_SPDX_EXT_REF
)
set(multi_args "")
@@ -273,9 +325,10 @@ function(_qt_internal_sbom_assemble_purl target)
string(APPEND purl "#${arg_PURL_SUBPATH}")
endif()
- _qt_internal_sbom_get_purl_value_extref(VALUE "${purl}" OUT_VAR result)
+ _qt_internal_sbom_get_purl_value_extref(VALUE "${purl}" OUT_VAR ext_ref_result)
- set(${arg_OUT_VAR} "${result}" PARENT_SCOPE)
+ set(${arg_OUT_VAR} "${purl}" PARENT_SCOPE)
+ set(${arg_OUT_VAR_SPDX_EXT_REF} "${ext_ref_result}" PARENT_SCOPE)
endfunction()
# Takes a PURL VALUE and returns an SBOM purl external reference in OUT_VAR.
diff --git a/cmake/QtPublicSbomPythonHelpers.cmake b/cmake/QtPublicSbomPythonHelpers.cmake
index f83314916f9..fef87af9ee4 100644
--- a/cmake/QtPublicSbomPythonHelpers.cmake
+++ b/cmake/QtPublicSbomPythonHelpers.cmake
@@ -12,6 +12,7 @@ macro(_qt_internal_sbom_find_python_and_dependency_helper_lambda)
DEPENDENCY_IMPORT_STATEMENT "${import_statement}"
OUT_VAR_PYTHON_PATH python_path
OUT_VAR_PYTHON_FOUND python_found
+ OUT_VAR_PYTHON_VERSION python_version
OUT_VAR_DEP_FOUND dep_found
OUT_VAR_PYTHON_AND_DEP_FOUND everything_found
OUT_VAR_DEP_FIND_OUTPUT dep_find_output
@@ -27,6 +28,7 @@ function(_qt_internal_sbom_find_python_and_dependency_helper)
set(single_args
OUT_VAR_PYTHON_PATH
OUT_VAR_PYTHON_FOUND
+ OUT_VAR_PYTHON_VERSION
OUT_VAR_DEP_FOUND
OUT_VAR_PYTHON_AND_DEP_FOUND
OUT_VAR_DEP_FIND_OUTPUT
@@ -65,6 +67,7 @@ function(_qt_internal_sbom_find_python_and_dependency_helper)
${arg_PYTHON_ARGS}
OUT_VAR_PYTHON_PATH python_path_inner
OUT_VAR_PYTHON_FOUND python_found_inner
+ OUT_VAR_PYTHON_VERSION python_version_inner
)
if(python_found_inner AND python_path_inner)
@@ -82,6 +85,9 @@ function(_qt_internal_sbom_find_python_and_dependency_helper)
set(${arg_OUT_VAR_PYTHON_PATH} "${python_path_inner}" PARENT_SCOPE)
set(${arg_OUT_VAR_PYTHON_FOUND} "${python_found_inner}" PARENT_SCOPE)
+ if(arg_OUT_VAR_PYTHON_VERSION)
+ set(${arg_OUT_VAR_PYTHON_VERSION} "${python_version_inner}" PARENT_SCOPE)
+ endif()
set(${arg_OUT_VAR_DEP_FOUND} "${dep_found_inner}" PARENT_SCOPE)
set(${arg_OUT_VAR_PYTHON_AND_DEP_FOUND} "${everything_found_inner}" PARENT_SCOPE)
set(${arg_OUT_VAR_DEP_FIND_OUTPUT} "${dep_find_output_inner}" PARENT_SCOPE)
@@ -90,7 +96,8 @@ endfunction()
# Tries to find the python intrepreter, given the QT_SBOM_PYTHON_INTERP path hint, as well as
# other options.
# Ignores any previously found python.
-# Returns the python interpreter path and whether it was successfully found.
+# Returns the python interpreter path and whether it was successfully found, along with the version
+# found.
#
# This is intentionally a function, and not a macro, to prevent overriding the Python3_EXECUTABLE
# non-cache variable in a global scope in case if a different python is found and used for a
@@ -109,6 +116,7 @@ function(_qt_internal_sbom_find_python_helper)
VERSION
OUT_VAR_PYTHON_PATH
OUT_VAR_PYTHON_FOUND
+ OUT_VAR_PYTHON_VERSION
)
set(multi_args "")
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
@@ -154,6 +162,9 @@ function(_qt_internal_sbom_find_python_helper)
set(${arg_OUT_VAR_PYTHON_PATH} "${Python3_EXECUTABLE}" PARENT_SCOPE)
set(${arg_OUT_VAR_PYTHON_FOUND} "${Python3_Interpreter_FOUND}" PARENT_SCOPE)
+ if(arg_OUT_VAR_PYTHON_VERSION)
+ set(${arg_OUT_VAR_PYTHON_VERSION} "${Python3_VERSION}" PARENT_SCOPE)
+ endif()
endfunction()
# Helper that takes an python import statement to run using the given python interpreter path,
@@ -186,7 +197,7 @@ function(_qt_internal_sbom_find_python_dependency_helper)
set(python_path "${arg_PYTHON_PATH}")
execute_process(
COMMAND
- ${python_path} -c "${arg_DEPENDENCY_IMPORT_STATEMENT}"
+ "${python_path}" -c "${arg_DEPENDENCY_IMPORT_STATEMENT}"
RESULT_VARIABLE res
OUTPUT_VARIABLE output
ERROR_VARIABLE output
@@ -197,7 +208,7 @@ function(_qt_internal_sbom_find_python_dependency_helper)
set(output "${output}")
else()
set(found FALSE)
- string(CONCAT output "SBOM Python dependency ${arg_DEPENDENCY_IMPORT_STATEMENT} not found. "
+ string(CONCAT output "SBOM Python dependency ${arg_DEPENDENCY_IMPORT_STATEMENT} NOT found. "
"Error:\n${output}")
endif()
@@ -245,6 +256,6 @@ function(_qt_internal_sbom_find_python_dependency_program)
set(message_type "STATUS")
set(prefix "Optional ")
endif()
- message(${message_type} "${prefix}SBOM python program '${program_name}' not found.")
+ message(${message_type} "${prefix}SBOM python program '${program_name}' NOT found.")
endif()
endfunction()
diff --git a/cmake/QtPublicSbomQtEntityHelpers.cmake b/cmake/QtPublicSbomQtEntityHelpers.cmake
index dfe3bf2be0a..d8d61eef42c 100644
--- a/cmake/QtPublicSbomQtEntityHelpers.cmake
+++ b/cmake/QtPublicSbomQtEntityHelpers.cmake
@@ -393,9 +393,11 @@ endfunction()
function(_qt_internal_sbom_handle_qt_entity_purl_entries)
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
list(APPEND single_args
- OUT_VAR # This is unused, but added by the calling function.
+ OUT_VAR_SPDX_EXT_REF_VALUES # This is unused, but added by the calling function.
+ OUT_VAR_PURL_VALUES # This is unused, but added by the calling function.
OUT_VAR_IDS
)
+
cmake_parse_arguments(PARSE_ARGV 0 arg "${opt_args}" "${single_args}" "${multi_args}")
_qt_internal_validate_all_args_are_parsed(arg)
@@ -418,7 +420,8 @@ endfunction()
function(_qt_internal_sbom_handle_qt_entity_purl target)
_qt_internal_get_sbom_purl_handling_options(opt_args single_args multi_args)
list(APPEND single_args
- OUT_VAR # This is unused, but added by the calling function.
+ OUT_VAR_SPDX_EXT_REF_VALUES # This is unused, but added by the calling function.
+ OUT_VAR_PURL_VALUES # This is unused, but added by the calling function.
OUT_PURL_ARGS
PURL_ID
)
diff --git a/cmake/QtSbomHelpers.cmake b/cmake/QtSbomHelpers.cmake
index 75694179fd1..c3ddc581427 100644
--- a/cmake/QtSbomHelpers.cmake
+++ b/cmake/QtSbomHelpers.cmake
@@ -194,3 +194,101 @@ function(qt_internal_extend_qt_entity_sbom target)
qt_internal_sbom_get_default_sbom_args("${target}" sbom_extra_args ${ARGN})
_qt_internal_extend_sbom(${target} ${ARGN} ${sbom_extra_args})
endfunction()
+
+# Helper function to convert a boolean SBOM option into a "yes" / "no" string.
+function(qt_internal_is_sbom_option_enabled var_name out_var)
+ if("${${var_name}}")
+ set(value "yes")
+ else()
+ set(value "no")
+ endif()
+ set(${out_var} "${value}" PARENT_SCOPE)
+endfunction()
+
+# Helper function to get a summary suffix for SBOM options that are enabled, but might be skipped
+# if their dependencies are missing.
+function(qt_internal_get_sbom_option_required_suffix var_name out_var)
+ if("${${var_name}}")
+ set(value "")
+ else()
+ set(value " (skipped if dependencies are missing)")
+ endif()
+ set(${out_var} "${value}" PARENT_SCOPE)
+endfunction()
+
+# Adds SBOM summary info to the configuration summary.
+function(qt_internal_add_sbom_summary_info)
+ qt_configure_add_summary_section(NAME "SBOM")
+
+ # Build SBOM info.
+ qt_internal_is_sbom_option_enabled(QT_GENERATE_SBOM value)
+ qt_configure_add_summary_entry(ARGS "Generate SBOM" TYPE "message" MESSAGE "${value}")
+
+ # Only show the details if generation is enabled.
+ if(QT_GENERATE_SBOM)
+ qt_internal_is_sbom_option_enabled(QT_SBOM_GENERATE_SPDX_V2 value)
+ qt_configure_add_summary_entry(ARGS "Generate SPDX v2.3"
+ TYPE "message" MESSAGE "${value}")
+
+ qt_internal_is_sbom_option_enabled(QT_SBOM_GENERATE_SPDX_V2_JSON value)
+ qt_internal_get_sbom_option_required_suffix(QT_SBOM_REQUIRE_GENERATE_SPDX_V2_JSON suffix)
+ qt_configure_add_summary_entry(ARGS "Generate SPDX v2.3 JSON"
+ TYPE "message" MESSAGE "${value}${suffix}")
+
+ qt_internal_is_sbom_option_enabled(QT_SBOM_VERIFY_SPDX_V2 value)
+ qt_internal_get_sbom_option_required_suffix(QT_SBOM_REQUIRE_VERIFY_SPDX_V2 suffix)
+ qt_configure_add_summary_entry(ARGS "Verify SPDX v2.3 JSON"
+ TYPE "message" MESSAGE "${value}${suffix}")
+
+ qt_internal_is_sbom_option_enabled(QT_SBOM_GENERATE_CYDX_V1_6 value)
+ qt_internal_get_sbom_option_required_suffix(QT_SBOM_REQUIRE_GENERATE_CYDX_V1_6 suffix)
+ qt_configure_add_summary_entry(ARGS "Generate CyloneDX v1.6"
+ TYPE "message" MESSAGE "${value}${suffix}")
+
+ qt_internal_is_sbom_option_enabled(QT_SBOM_VERIFY_CYDX_V1_6 value)
+ qt_internal_get_sbom_option_required_suffix(QT_SBOM_REQUIRE_VERIFY_CYDX_V1_6 suffix)
+ qt_configure_add_summary_entry(ARGS "Verify CyloneDX v1.6"
+ TYPE "message" MESSAGE "${value}${suffix}")
+
+ # Python interpreter info.
+ if(QT_INTERNAL_SBOM_PYTHON_EXECUTABLE)
+ set(value "${QT_INTERNAL_SBOM_PYTHON_EXECUTABLE}")
+ string(APPEND value " (version ${QT_INTERNAL_SBOM_PYTHON_VERSION})")
+ else()
+ set(value "Not found")
+ endif()
+ qt_configure_add_summary_entry(ARGS "SBOM Python interpreter"
+ TYPE "message" MESSAGE "${value}")
+
+ # These are kinda internal, so only show them when found.
+ if(QT_SBOM_PROGRAM_SBOM2DOC)
+ set(value "${QT_SBOM_PROGRAM_SBOM2DOC}")
+ qt_configure_add_summary_entry(ARGS "sbom2doc path" TYPE "message" MESSAGE "${value}")
+ endif()
+
+ if(QT_SBOM_PROGRAM_SBOMAUDIT)
+ set(value "${QT_SBOM_PROGRAM_SBOMAUDIT}")
+ qt_configure_add_summary_entry(ARGS "sbomaudit path" TYPE "message" MESSAGE "${value}")
+ endif()
+ endif()
+
+ # Source SBOM info.
+ qt_internal_is_sbom_option_enabled(QT_GENERATE_SOURCE_SBOM value)
+ qt_configure_add_summary_entry(ARGS "Generate source SPDX SBOM"
+ TYPE "message" MESSAGE "${value}")
+
+ if(QT_GENERATE_SOURCE_SBOM)
+ qt_internal_is_sbom_option_enabled(QT_LINT_SOURCE_SBOM value)
+ qt_configure_add_summary_entry(ARGS "Verify source SPDX SBOM"
+ TYPE "message" MESSAGE "${value}")
+
+ if(QT_SBOM_PROGRAM_REUSE)
+ set(value "${QT_SBOM_PROGRAM_REUSE}")
+ else()
+ set(value "Not found")
+ endif()
+ qt_configure_add_summary_entry(ARGS "reuse path" TYPE "message" MESSAGE "${value}")
+ endif()
+
+ qt_configure_end_summary_section()
+endfunction()
diff --git a/cmake/QtTargetHelpers.cmake b/cmake/QtTargetHelpers.cmake
index 632fb5b5644..7b2d51d69a7 100644
--- a/cmake/QtTargetHelpers.cmake
+++ b/cmake/QtTargetHelpers.cmake
@@ -841,13 +841,12 @@ function(qt_internal_export_additional_targets_file)
qt_internal_append_export_additional_targets()
- set_property(GLOBAL APPEND PROPERTY _qt_export_additional_targets_ids "${id}")
set_property(GLOBAL APPEND
PROPERTY _qt_export_additional_targets_export_name_prefix_${id} "${arg_EXPORT_NAME_PREFIX}")
set_property(GLOBAL APPEND
PROPERTY _qt_export_additional_targets_config_install_dir_${id} "${arg_CONFIG_INSTALL_DIR}")
- qt_add_list_file_finalizer(qt_internal_export_additional_targets_file_finalizer)
+ qt_add_list_file_finalizer(qt_internal_export_additional_targets_file_finalizer "${id}")
endfunction()
function(qt_internal_get_export_additional_targets_id export_name out_var)
@@ -913,19 +912,9 @@ function(qt_internal_validate_export_additional_targets)
set(arg_TARGET_EXPORT_NAMES "${arg_TARGET_EXPORT_NAMES}" PARENT_SCOPE)
endfunction()
-# The finalizer might be called multiple times in the same scope, but only the first one will
-# process all the ids.
-function(qt_internal_export_additional_targets_file_finalizer)
- get_property(ids GLOBAL PROPERTY _qt_export_additional_targets_ids)
-
- foreach(id ${ids})
- qt_internal_export_additional_targets_file_handler("${id}")
- endforeach()
-
- set_property(GLOBAL PROPERTY _qt_export_additional_targets_ids "")
-endfunction()
-
-function(qt_internal_export_additional_targets_file_handler id)
+# The finalizer might be called multiple times in the same directory scope, but it will only process
+# one specific id.
+function(qt_internal_export_additional_targets_file_finalizer id)
get_property(arg_EXPORT_NAME_PREFIX GLOBAL PROPERTY
_qt_export_additional_targets_export_name_prefix_${id})
get_property(arg_CONFIG_INSTALL_DIR GLOBAL PROPERTY
diff --git a/cmake/QtWrapperScriptHelpers.cmake b/cmake/QtWrapperScriptHelpers.cmake
index ecdc043c49c..f76d52bca91 100644
--- a/cmake/QtWrapperScriptHelpers.cmake
+++ b/cmake/QtWrapperScriptHelpers.cmake
@@ -235,6 +235,7 @@ export CMAKE_GENERATOR=Xcode
qt_internal_create_qt_configure_part_wrapper_script("STANDALONE_TESTS")
qt_internal_create_qt_configure_part_wrapper_script("STANDALONE_EXAMPLES")
+ qt_internal_create_cyclone_dx_sbom_generator_script()
if(NOT CMAKE_CROSSCOMPILING)
qt_internal_create_qt_android_runner_wrapper_script()
@@ -381,6 +382,23 @@ function(qt_internal_create_qt_configure_redo_script)
set_property(GLOBAL PROPERTY _qt_configure_redo_script_created TRUE)
endfunction()
+function(qt_internal_create_cyclone_dx_sbom_generator_script)
+ _qt_internal_sbom_get_cyclone_dx_generator_script_name(generator_name generator_relative_dir)
+
+ qt_path_join(build_dir_destination "${QT_BUILD_DIR}" "${INSTALL_LIBEXECDIR}")
+ qt_path_join(install_destination "${QT_INSTALL_DIR}" "${INSTALL_LIBEXECDIR}")
+ qt_path_join(script_path
+ "${CMAKE_CURRENT_SOURCE_DIR}" "${generator_relative_dir}" "${generator_name}")
+
+ if(QT_WILL_INSTALL)
+ file(COPY "${script_path}"
+ DESTINATION "${build_dir_destination}"
+ )
+ endif()
+
+ qt_copy_or_install(PROGRAMS "${script_path}" DESTINATION "${install_destination}")
+endfunction()
+
function(qt_internal_create_qt_android_runner_wrapper_script)
qt_path_join(android_runner_destination "${QT_INSTALL_DIR}" "${INSTALL_LIBEXECDIR}")
qt_path_join(android_runner "${CMAKE_CURRENT_SOURCE_DIR}" "libexec" "qt-android-runner.py")
diff --git a/cmake/configure-cmake-mapping.md b/cmake/configure-cmake-mapping.md
index 95b1215ddce..72a30cd87b3 100644
--- a/cmake/configure-cmake-mapping.md
+++ b/cmake/configure-cmake-mapping.md
@@ -45,11 +45,16 @@ The following table describes the mapping of configure options to CMake argument
| -device-option <key=value> | -DQT_QMAKE_DEVICE_OPTIONS=key1=value1;key2=value2 | Only used for generation qmake-compatibility files. |
| | | The device options are written into mkspecs/qdevice.pri. |
| -appstore-compliant | -DFEATURE_appstore_compliant=ON | |
-| -sbom | -DQT_GENERATE_SBOM=ON | Enables generation and installation of a SPDX SBOM documents |
-| -sbom-json | -DQT_SBOM_GENERATE_JSON=ON | Enables generation of SPDX SBOM in JSON format |
-| -sbom-json-required | -DQT_SBOM_REQUIRE_GENERATE_JSON=ON | Fails the build if Python deps are not found |
-| -sbom-verify | -DQT_SBOM_VERIFY=ON | Enables verification of generated SBOMs |
-| -sbom-verify-required | -DQT_SBOM_REQUIRE_VERIFY=ON | Fails the build if Python deps are not found |
+| -sbom | -DQT_GENERATE_SBOM=ON | Enables generation of SBOM documents (multiple formats) |
+| -sbom-spdx-v2 | -DQT_SBOM_GENERATE_SPDX_V2=ON | Enables generation of SPDX v2.3 SBOM in tag:value format |
+| -sbom-cyclonedx-v1_6 | -DQT_SBOM_GENERATE_CYDX_V1_6=ON | Enables generation of CycloneDX v1.6 SBOM in JSON format |
+| -sbom-cyclonedx-v1_6-required | -DQT_SBOM_REQUIRE_GENERATE_CYDX_V1_6=ON | Fails the build if Cyclone DX Python deps are not found |
+| -sbom-cyclonedx-v1_6-verify | -DQT_SBOM_VERIFY_CYDX_V1_6=ON | Enables verification of generated CycloneDX v1.6 SBOMs |
+| -sbom-cyclonedx-v1_6-verify-required | -DQT_SBOM_REQUIRE_VERIFY_CYDX_V1_6=ON | Fails the build if Cyclone DX Python verify deps are not found |
+| -sbom-json | -DQT_SBOM_GENERATE_SPDX_V2_JSON=ON | Enables generation of SPDX v2.3 SBOM in JSON format |
+| -sbom-json-required | -DQT_SBOM_REQUIRE_GENERATE_SPDX_V2_JSON=ON | Fails the build if SPDX Python deps are not found |
+| -sbom-verify | -DQT_SBOM_VERIFY_SPDX_V2=ON | Enables verification of generated SPDX v2.3 SBOMs |
+| -sbom-verify-required | -DQT_SBOM_REQUIRE_VERIFY_SPDX_V2=ON | Fails the build if SPDX Python verify deps are not found |
| -sbomdir <dir> | -DINSTALL_SBOMDIR=<dir> | Installation location of SBOM files. |
| -qtinlinenamespace | -DQT_INLINE_NAMESPACE=ON | Make the namespace specified by -qtnamespace an inline one. |
| -qtnamespace <name> | -DQT_NAMESPACE=<name> | |
@@ -128,7 +133,6 @@ The following table describes the mapping of configure options to CMake argument
| -glib | -DFEATURE_glib=ON | |
| -inotify | -DFEATURE_inotify=ON | |
| -icu | -DFEATURE_icu=ON | |
-| -pcre | -DFEATURE_pcre2=ON | |
| -pcre [system/qt] | -DFEATURE_system_pcre2=ON/OFF | |
| -pps | n/a | QNX feature. Not available for 6.0. |
| -zlib [system/qt] | -DFEATURE_system_zlib=ON/OFF | |
diff --git a/coin/instructions/prepare_building_env.yaml b/coin/instructions/prepare_building_env.yaml
index 2cc63b136e4..ed13c0bd0cc 100644
--- a/coin/instructions/prepare_building_env.yaml
+++ b/coin/instructions/prepare_building_env.yaml
@@ -549,18 +549,25 @@ instructions:
property: features
contains_value: GenerateSBOM
instructions:
+ - type: EnvironmentVariable
+ variableName: SBOM_COMMON_ARGS
+ variableValue: >-
+ -DQT_GENERATE_SBOM=ON
+ -DQT_GENERATE_SOURCE_SBOM=ON
+ -DQT_SBOM_REQUIRE_GENERATE_CYDX_V1_6=ON
+ -DQT_SBOM_VERIFY_CYDX_V1_6=ON
- type: AppendToEnvironmentVariable
variableName: COMMON_CMAKE_ARGS
- variableValue: " -DQT_GENERATE_SBOM=ON -DQT_GENERATE_SOURCE_SBOM=ON"
+ variableValue: " {{.Env.SBOM_COMMON_ARGS}} "
- type: AppendToEnvironmentVariable
variableName: COMMON_NON_QTBASE_CMAKE_ARGS
- variableValue: " -DQT_GENERATE_SBOM=ON -DQT_GENERATE_SOURCE_SBOM=ON"
+ variableValue: " {{.Env.SBOM_COMMON_ARGS}} "
- type: AppendToEnvironmentVariable
variableName: COMMON_TARGET_CMAKE_ARGS
- variableValue: " -DQT_GENERATE_SBOM=ON -DQT_GENERATE_SOURCE_SBOM=ON"
+ variableValue: " {{.Env.SBOM_COMMON_ARGS}} "
- type: AppendToEnvironmentVariable
variableName: COMMON_NON_QTBASE_TARGET_CMAKE_ARGS
- variableValue: " -DQT_GENERATE_SBOM=ON -DQT_GENERATE_SOURCE_SBOM=ON"
+ variableValue: " {{.Env.SBOM_COMMON_ARGS}} "
# SBOM Python apps path. On Windows python-installed apps are
# in the same directory where pip is, aka Scripts sub-directory.
diff --git a/coin/instructions/vxworks_test_env_setup.yaml b/coin/instructions/vxworks_test_env_setup.yaml
index 9ff710fbc7f..9e40b21acc4 100644
--- a/coin/instructions/vxworks_test_env_setup.yaml
+++ b/coin/instructions/vxworks_test_env_setup.yaml
@@ -67,6 +67,7 @@ instructions:
env_vars["QTEST_FUNCTION_TIMEOUT"]="1000000"
env_vars["QT_PLUGIN_PATH"]="/home/qt/work/install/target/plugins"
env_vars["QT_QPA_PLATFORM_PLUGIN_PATH"]="/home/qt/work/install/target/plugins/platforms"
+ env_vars["TZ"]="UTC"
for i in "${!hosts[@]}"
do
diff --git a/config_help.txt b/config_help.txt
index 27b80654fab..dcd57bdfbc0 100644
--- a/config_help.txt
+++ b/config_help.txt
@@ -274,7 +274,7 @@ Core options:
-inotify ............. Enable inotify support
-icu ................. Enable ICU support [auto]
-jemalloc ............ Enable jemalloc support and cooperation [no]
- -pcre ................ Select used libpcre2 [system/qt/no]
+ -pcre ................ Select used libpcre2 [system/qt]
-zlib ................ Select used zlib [system/qt]
Logging backends:
diff --git a/doc/global/config.qdocconf b/doc/global/config.qdocconf
index 0adfe36f516..0baf9a15478 100644
--- a/doc/global/config.qdocconf
+++ b/doc/global/config.qdocconf
@@ -42,5 +42,8 @@ qhp = true
# Disable writing host-specific paths into .index files
locationinfo = false
+# Automatically mark classes declared in private headers as \internal
+internalfilepatterns = *_p.h
+
# Include the warninglimit used for documentation testing in CI
include(warninglimit.qdocconf)
diff --git a/examples/widgets/doc/images/treemodel-structure.svg b/examples/widgets/doc/images/treemodel-structure.svg
index f8bc24803bf..8f86ff33862 100644
--- a/examples/widgets/doc/images/treemodel-structure.svg
+++ b/examples/widgets/doc/images/treemodel-structure.svg
@@ -1,93 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
- preserveAspectRatio="none"
- width="192"
- height="350"
- viewBox="-25 -30 153.6 280"
- version="1.1"
- xmlns="http://www.w3.org/2000/svg">
+ viewBox="0 0 165 300"
+ width="165"
+ height="300"
+ version="1.1"
+ id="svg25"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+
+<style>
+ svg .line-style { stroke: black; fill: none }
+ svg .text-style { font: 12px arial; fill: black }
+ svg .bold-style { font: 12px arial; fill: black; font-weight: bold }
+ svg .item-style { font: 16px arial; fill: black }
+
+ [data-theme="dark"] svg .line-style { stroke: #f2f2f2; fill: none }
+ [data-theme="dark"] svg .text-style { font: 12px arial; fill: #f2f2f2 }
+ [data-theme="dark"] svg .bold-style { font: 12px arial; fill: #f2f2f2; font-weight: bold }
+ [data-theme="dark"] svg .item-style { font: 14px arial; fill: #f2f2f2 }
+
+ [data-theme="light"] svg .line-style { stroke: black; fill: none }
+ [data-theme="light"] svg .text-style { font: 12px arial; fill: black }
+ [data-theme="light"] svg .bold-style { font: 12px arial; fill: black; font-weight: bold }
+ [data-theme="light"] svg .item-style { font: 14px arial; fill: black }
+</style>
<!-- Root node -->
-<g transform="translate(0, 0)">
-<path fill="none" stroke="#333" stroke-dasharray="4" d="M -10 -10 l 20 0 l 0 20 l -20 0 z" />
-<text x="15" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="left" dominant-baseline="central" font-weight="bold">
- Root item (empty)
-</text>
-</g>
+<text x="50" y="29" class="bold-style">Root item (empty)</text>
+<path d="M 10,10 L 40,10 L 40,40 L 10,40 Z" class="line-style"
+ stroke-dasharray="5 5" />
<!-- Root spine vertical line solid part -->
-<path fill="none" stroke="#333" d="M 0 10 l 0 190" />
-
+<path d="M 25,40 L 25,265" class="line-style" />
<!-- Root spine vertical line dotted continuation -->
-<path fill="none" stroke="#333" stroke-dasharray="4" d="M 0 200 l 0 30" />
+<path d="M 25,265 L 25,290" class="line-style" stroke-dasharray="3 3" />
-<!-- Horizontal lines from Root spine to children A, E, F -->
-<path fill="none" stroke="#333" d="M 0 40 l 20 0" />
-<path fill="none" stroke="#333" d="M 0 160 l 20 0" />
-<path fill="none" stroke="#333" d="M 0 185 l 20 0" />
+<!-- Horizontal lines from Root spine to children A, C, ... -->
+<path d="M 25,65 L 45,65" class="line-style" />
+<path d="M 25,225 L 45,225" class="line-style" />
+<path d="M 25,265 L 45,265" class="line-style" />
<!-- Node A with label [0] -->
-<g transform="translate(30, 40)">
-<path fill="none" stroke="#333" d="M -10 -10 l 20 0 l 0 20 l -20 0 z"/>
-<text x="0" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="middle" dominant-baseline="central">
- A
-</text>
-<text x="15" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="start" dominant-baseline="central">
- row = 0
-</text>
-</g>
+<path d="M 45,50 L 75,50 L 75,80 L 45,80 Z" class="line-style" />
+<text x="55" y="70" class="item-style">A</text>
+<text x="82" y="69" class="text-style">row = 0</text>
<!-- Vertical line from A to its children -->
-<path fill="none" stroke="#333" d="M 30 50 l 0 80" />
+<path d="M 60,80 L 60,185" class="line-style" />
-<!-- Horizontal lines from A's spine to B, C, D -->
-<path fill="none" stroke="#333" d="M 30 70 l 20 0" />
-<path fill="none" stroke="#333" d="M 30 100 l 20 0" />
-<path fill="none" stroke="#333" d="M 30 130 l 20 0" />
+<!-- Horizontal lines from A's spine to ..., B, ... -->
+<path d="M 60,105 L 80,105" class="line-style" />
+<path d="M 60,145 L 80,145" class="line-style" />
+<path d="M 60,185 L 80,185" class="line-style" />
-<!-- Node B -->
-<g transform="translate(60, 70)">
-<path fill="none" stroke="#333" d="M -10 -10 l 20 0 l 0 20 l -20 0 z"/>
-<text x="15" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="start" dominant-baseline="central">
- row = 0
-</text>
-</g>
+<!-- First unnamed child node of A -->
+<path d="M 80,90 L 110,90 L 110,120 L 80,120 Z" class="line-style" />
+<text x="117" y="109" class="text-style">row = 0</text>
-<!-- Node C -->
-<g transform="translate(60, 100)">
-<path fill="none" stroke="#333" d="M -10 -10 l 20 0 l 0 20 l -20 0 z"/>
-<text x="0" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="middle" dominant-baseline="central">
- B
-</text>
-<text x="15" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="start" dominant-baseline="central">
- row = 1
-</text>
-</g>
-
-<!-- Node D -->
-<g transform="translate(60, 130)">
-<path fill="none" stroke="#333" d="M -10 -10 l 20 0 l 0 20 l -20 0 z"/>
-<text x="15" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="start" dominant-baseline="central">
- row = 2
-</text>
-</g>
+<!-- Node B -->
+<path d="M 80,130 L 110,130 L 110,160 L 80,160 Z" class="line-style" />
+<text x="90" y="150" class="item-style">B</text>
+<text x="117" y="149" class="text-style">row = 1</text>
-<!-- Node E -->
-<g transform="translate(30, 160)">
-<path fill="none" stroke="#333" d="M -10 -10 l 20 0 l 0 20 l -20 0 z"/>
-<text x="0" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="middle" dominant-baseline="central">
- C
-</text>
-<text x="15" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="start" dominant-baseline="central">
- row = 1
-</text>
-</g>
+<!-- Last unnamed child node of A -->
+<path d="M 80,170 L 110,170 L 110,200 L 80,200 Z" class="line-style" />
+<text x="117" y="189" class="text-style">row = 2</text>
-<!-- Node F -->
-<g transform="translate(30, 185)">
-<path fill="none" stroke="#333" d="M -10 -10 l 20 0 l 0 20 l -20 0 z"/>
-<text x="15" y="0" font-size="12" font-family="Arial" fill="#333" text-anchor="start" dominant-baseline="central">
- row = 2
-</text>
-</g>
+<!-- Node C -->
+<path d="M 45,210 L 75,210 L 75,240 L 45,240 Z" class="line-style" />
+<text x="55" y="230" class="item-style">C</text>
+<text x="82" y="229" class="text-style">row = 1</text>
+<!-- Last visible child node of the root node -->
+<path d="M 45,250 L 75,250 L 75,280 L 45,280 Z" class="line-style" />
+<text x="82" y="269" class="text-style">row = 2</text>
</svg>
diff --git a/licenseRule.json b/licenseRule.json
index 3bc58bddca9..8c4029f91e1 100644
--- a/licenseRule.json
+++ b/licenseRule.json
@@ -377,6 +377,11 @@
"file type": "util",
"spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"]
},
+ "util/sbom/cyclonedx/pyproject.toml": {
+ "comment": "Default",
+ "file type": "util",
+ "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"]
+ },
"util/unicode/data/.*\\.txt": {
"comment": "Exception.",
"file type": "3rd party",
diff --git a/src/3rdparty/double-conversion/0001-fix-decimal_point-initialization-to-suppress-warning.patch b/src/3rdparty/double-conversion/0001-fix-decimal_point-initialization-to-suppress-warning.patch
new file mode 100644
index 00000000000..2dd58d4b818
--- /dev/null
+++ b/src/3rdparty/double-conversion/0001-fix-decimal_point-initialization-to-suppress-warning.patch
@@ -0,0 +1,40 @@
+From c75f7f48c8a3d9c6aaaeb13a48fb3c051b46ccab Mon Sep 17 00:00:00 2001
+From: Ivan Solovev <[email protected]>
+Date: Mon, 3 Nov 2025 12:33:26 +0100
+Subject: [PATCH] fix decimal_point initialization to suppress warnings in GCC
+ 14
+
+This patch was submitted upstream as [0], but there was no new release
+yet.
+
+[0]: https://github.com/google/double-conversion/commit/4aecc844c566d84a939fc35f4e62d58bd693f18d
+
+Change-Id: I97cc3103ff758f4c65b23d2f4c0fd82932e36df7
+---
+ .../double-conversion/double-conversion/double-to-string.cc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/double-conversion/double-conversion/double-to-string.cc b/src/3rdparty/double-conversion/double-conversion/double-to-string.cc
+index 215eaa96d47..9ea3d18d5f7 100644
+--- a/src/3rdparty/double-conversion/double-conversion/double-to-string.cc
++++ b/src/3rdparty/double-conversion/double-conversion/double-to-string.cc
+@@ -180,7 +180,7 @@ bool DoubleToStringConverter::ToShortestIeeeNumber(
+ return HandleSpecialValues(value, result_builder);
+ }
+
+- int decimal_point;
++ int decimal_point = 0;
+ bool sign;
+ const int kDecimalRepCapacity = kBase10MaximalLength + 1;
+ char decimal_rep[kDecimalRepCapacity];
+@@ -405,6 +405,7 @@ void DoubleToStringConverter::DoubleToAscii(double v,
+ if (mode == PRECISION && requested_digits == 0) {
+ vector[0] = '\0';
+ *length = 0;
++ *point = 0;
+ return;
+ }
+
+--
+2.44.0
+
diff --git a/src/3rdparty/double-conversion/REUSE.toml b/src/3rdparty/double-conversion/REUSE.toml
index a7ebffce4f0..14e6e9b6706 100644
--- a/src/3rdparty/double-conversion/REUSE.toml
+++ b/src/3rdparty/double-conversion/REUSE.toml
@@ -1,7 +1,7 @@
version = 1
[[annotations]]
-path = ["double-conversion/*"]
+path = ["double-conversion/*", "0001-fix-decimal_point-initialization-to-suppress-warning.patch"]
precedence = "closest"
SPDX-FileCopyrightText = "Copyright 2006-2012, the V8 project authors"
SPDX-License-Identifier = "BSD-3-Clause"
diff --git a/src/3rdparty/double-conversion/double-conversion/double-to-string.cc b/src/3rdparty/double-conversion/double-conversion/double-to-string.cc
index 215eaa96d47..9ea3d18d5f7 100644
--- a/src/3rdparty/double-conversion/double-conversion/double-to-string.cc
+++ b/src/3rdparty/double-conversion/double-conversion/double-to-string.cc
@@ -180,7 +180,7 @@ bool DoubleToStringConverter::ToShortestIeeeNumber(
return HandleSpecialValues(value, result_builder);
}
- int decimal_point;
+ int decimal_point = 0;
bool sign;
const int kDecimalRepCapacity = kBase10MaximalLength + 1;
char decimal_rep[kDecimalRepCapacity];
@@ -405,6 +405,7 @@ void DoubleToStringConverter::DoubleToAscii(double v,
if (mode == PRECISION && requested_digits == 0) {
vector[0] = '\0';
*length = 0;
+ *point = 0;
return;
}
diff --git a/src/3rdparty/pcre2/AUTHORS.md b/src/3rdparty/pcre2/AUTHORS.md
index 708fc2325ce..ced81e68adc 100644
--- a/src/3rdparty/pcre2/AUTHORS.md
+++ b/src/3rdparty/pcre2/AUTHORS.md
@@ -1,14 +1,14 @@
PCRE2 Authorship and Contributors
=================================
-COPYRIGHT
+Copyright
---------
Please see the file [LICENCE](./LICENCE.md) in the PCRE2 distribution for
copyright details.
-MAINTAINERS
+Maintainers
-----------
The PCRE and PCRE2 libraries were authored and maintained by Philip Hazel.
@@ -62,7 +62,7 @@ Both administrators are volunteers acting in a personal capacity.
</table>
-CONTRIBUTORS
+Contributors
------------
Many others have participated and contributed to PCRE2 over its history.
@@ -77,7 +77,7 @@ All names listed alphabetically.
### Contributors to PCRE2
-This list includes names up until the PCRE2 10.44 release. New names will be
+This list includes names up until the PCRE2 10.47 release. New names will be
added from the Git history on each release.
Scott Bell
@@ -93,13 +93,16 @@ added from the Git history on each release.
Addison Crump
Alex Dowad
Daniel Engberg
+ Marco Feuerstein
Daniel Richard G
+ Isaac Oscar Gariano
David Gaussmann
Andrey Gorbachev
Jordan Griege
Jason Hood
Bumsu Hyeon
Roy Ivy
+ Nobuhiro Iwamatsu
Martin Joerg
Guillem Jover
Ralf Junker
@@ -114,13 +117,17 @@ added from the Git history on each release.
Kai Lu
Behzod Mansurov
B. Scott Michel
+ Greg Minshall
Nathan Moinvaziri
Mike Munday
Marc Mutz
Fabio Pagani
Christian Persch
+ Alex Reinking
+ Joshua Rogers
Tristan Ross
William A Rowe Jr
+ Rocco Ruscitti
David Seifert
Yaakov Selkowitz
Rich Siegel
@@ -131,6 +138,7 @@ added from the Git history on each release.
Greg Thain
Lucas Trzesniewski
Theodore Tsirpanis
+ Aaron M. Ucko
Matthew Vernon
Rémi Verschelde
Thomas Voss
diff --git a/src/3rdparty/pcre2/CMakeLists.txt b/src/3rdparty/pcre2/CMakeLists.txt
index 6b4cd1b1cc3..3f4a4677787 100644
--- a/src/3rdparty/pcre2/CMakeLists.txt
+++ b/src/3rdparty/pcre2/CMakeLists.txt
@@ -15,6 +15,7 @@ qt_internal_add_3rdparty_library(BundledPcre2
src/pcre2_chartables.c
src/pcre2_chkdint.c
src/pcre2_compile.c
+ src/pcre2_compile_cgroup.c
src/pcre2_compile_class.c
src/pcre2_config.c
src/pcre2_context.c
diff --git a/src/3rdparty/pcre2/LICENCE.md b/src/3rdparty/pcre2/LICENCE.md
index f58ceb75a63..f6fba35db25 100644
--- a/src/3rdparty/pcre2/LICENCE.md
+++ b/src/3rdparty/pcre2/LICENCE.md
@@ -1,4 +1,4 @@
-PCRE2 License
+PCRE2 Licence
=============
| SPDX-License-Identifier: | BSD-3-Clause WITH PCRE2-exception |
@@ -16,7 +16,8 @@ testdata directory is not copyrighted and is in the public domain.
The basic library functions are written in C and are freestanding. Also
included in the distribution is a just-in-time compiler that can be used to
optimize pattern matching. This is an optional feature that can be omitted when
-the library is built.
+the library is built. The just-in-time compiler is separately licensed under the
+"2-clause BSD" licence.
COPYRIGHT
@@ -53,6 +54,8 @@ COPYRIGHT
Copyright (c) 2009-2024 Zoltan Herczeg
All rights reserved.
+The code in the `deps/sljit` directory has its own LICENSE file.
+
### All other contributions
Many other contributors have participated in the authorship of PCRE2. As PCRE2
@@ -99,5 +102,3 @@ not apply all the way down a chain of software. If binary package A includes
PCRE2, it must respect the condition, but if package B is software that
includes package A, the condition is not imposed on package B unless it uses
PCRE2 independently.
-
-End
diff --git a/src/3rdparty/pcre2/LICENCE-SLJIT b/src/3rdparty/pcre2/LICENSE-SLJIT
index 0aaecaaa286..0aaecaaa286 100644
--- a/src/3rdparty/pcre2/LICENCE-SLJIT
+++ b/src/3rdparty/pcre2/LICENSE-SLJIT
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorCore.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorCore.c
index 4e1119bc40c..314483c7ae7 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorCore.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/allocator_src/sljitExecAllocatorCore.c
@@ -49,9 +49,9 @@
n - The size of the previous block.
Using these size values we can go forward or backward on the block chain.
- The unused blocks are stored in a chain list pointed by free_blocks. This
- list is useful if we need to find a suitable memory area when the allocator
- is called.
+ The unused blocks are stored in a chain list pointed by sljit_free_blocks.
+ This list is useful if we need to find a suitable memory area when the
+ allocator is called.
When a block is freed, the new free block is connected to its adjacent free
blocks if possible.
@@ -115,20 +115,20 @@ struct free_block {
#define ALIGN_SIZE(size) (((size) + sizeof(struct block_header) + 7u) & ~(sljit_uw)7)
#define CHUNK_EXTRA_SIZE (sizeof(struct block_header) + CHUNK_HEADER_SIZE)
-static struct free_block* free_blocks;
-static sljit_uw allocated_size;
-static sljit_uw total_size;
+static struct free_block* sljit_free_blocks;
+static sljit_uw sljit_allocated_size;
+static sljit_uw sljit_total_size;
static SLJIT_INLINE void sljit_insert_free_block(struct free_block *free_block, sljit_uw size)
{
free_block->header.size = 0;
free_block->size = size;
- free_block->next = free_blocks;
+ free_block->next = sljit_free_blocks;
free_block->prev = NULL;
- if (free_blocks)
- free_blocks->prev = free_block;
- free_blocks = free_block;
+ if (sljit_free_blocks)
+ sljit_free_blocks->prev = free_block;
+ sljit_free_blocks = free_block;
}
static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
@@ -139,8 +139,8 @@ static SLJIT_INLINE void sljit_remove_free_block(struct free_block *free_block)
if (free_block->prev)
free_block->prev->next = free_block->next;
else {
- SLJIT_ASSERT(free_blocks == free_block);
- free_blocks = free_block->next;
+ SLJIT_ASSERT(sljit_free_blocks == free_block);
+ sljit_free_blocks = free_block->next;
}
}
@@ -166,7 +166,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
size = ALIGN_SIZE(size);
SLJIT_ALLOCATOR_LOCK();
- free_block = free_blocks;
+ free_block = sljit_free_blocks;
while (free_block) {
if (free_block->size >= size) {
chunk_size = free_block->size;
@@ -186,7 +186,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
header = (struct block_header*)free_block;
size = chunk_size;
}
- allocated_size += size;
+ sljit_allocated_size += size;
header->size = size;
SLJIT_ALLOCATOR_UNLOCK();
return MEM_START(header);
@@ -207,7 +207,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
chunk_size -= CHUNK_EXTRA_SIZE;
- total_size += chunk_size;
+ sljit_total_size += chunk_size;
header = (struct block_header*)(((sljit_u8*)chunk_header) + CHUNK_HEADER_SIZE);
@@ -218,7 +218,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
if (chunk_size > size + 64) {
/* Cut the allocated space into a free and a used block. */
- allocated_size += size;
+ sljit_allocated_size += size;
header->size = size;
chunk_size -= size;
@@ -231,7 +231,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_malloc_exec(sljit_uw size)
next_header = AS_BLOCK_HEADER(free_block, chunk_size);
} else {
/* All space belongs to this allocation. */
- allocated_size += chunk_size;
+ sljit_allocated_size += chunk_size;
header->size = chunk_size;
next_header = AS_BLOCK_HEADER(header, chunk_size);
}
@@ -254,7 +254,7 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void *ptr)
#ifdef SLJIT_HAS_EXECUTABLE_OFFSET
header = AS_BLOCK_HEADER(header, -header->executable_offset);
#endif /* SLJIT_HAS_EXECUTABLE_OFFSET */
- allocated_size -= header->size;
+ sljit_allocated_size -= header->size;
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
@@ -282,9 +282,9 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_exec(void *ptr)
/* The whole chunk is free. */
if (SLJIT_UNLIKELY(!free_block->header.prev_size && header->size == 1)) {
- /* If this block is freed, we still have (allocated_size / 2) free space. */
- if (total_size - free_block->size > (allocated_size * 3 / 2)) {
- total_size -= free_block->size;
+ /* If this block is freed, we still have (sljit_allocated_size / 2) free space. */
+ if (sljit_total_size - free_block->size > (sljit_allocated_size * 3 / 2)) {
+ sljit_total_size -= free_block->size;
sljit_remove_free_block(free_block);
free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE);
}
@@ -302,19 +302,19 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_free_unused_memory_exec(void)
SLJIT_ALLOCATOR_LOCK();
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 0);
- free_block = free_blocks;
+ free_block = sljit_free_blocks;
while (free_block) {
next_free_block = free_block->next;
if (!free_block->header.prev_size &&
AS_BLOCK_HEADER(free_block, free_block->size)->size == 1) {
- total_size -= free_block->size;
+ sljit_total_size -= free_block->size;
sljit_remove_free_block(free_block);
free_chunk(free_block, free_block->size + CHUNK_EXTRA_SIZE);
}
free_block = next_free_block;
}
- SLJIT_ASSERT(total_size || (!total_size && !free_blocks));
+ SLJIT_ASSERT(sljit_total_size || (!sljit_total_size && !sljit_free_blocks));
SLJIT_UPDATE_WX_FLAGS(NULL, NULL, 1);
SLJIT_ALLOCATOR_UNLOCK();
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitConfigInternal.h b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitConfigInternal.h
index 3ae944efb81..c052434d2f5 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitConfigInternal.h
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitConfigInternal.h
@@ -71,6 +71,7 @@
SLJIT_SEPARATE_VECTOR_REGISTERS : if this macro is defined, the vector registers do not
overlap with floating point registers
SLJIT_WORD_SHIFT : the shift required to apply when accessing a sljit_sw/sljit_uw array by index
+ SLJIT_POINTER_SHIFT : the shift required to apply when accessing a sljit_sp/sljit_up array by index
SLJIT_F32_SHIFT : the shift required to apply when accessing
a single precision floating point array by index
SLJIT_F64_SHIFT : the shift required to apply when accessing
@@ -96,15 +97,21 @@
SLJIT_TMP_FR(i) : accessing temporary floating point registers
SLJIT_TMP_VR0 .. VR9 : accessing temporary vector registers
SLJIT_TMP_VR(i) : accessing temporary vector registers
- SLJIT_TMP_DEST_REG : a temporary register for results
- SLJIT_TMP_MEM_REG : a temporary base register for accessing memory
- (can be the same as SLJIT_TMP_DEST_REG)
- SLJIT_TMP_DEST_FREG : a temporary register for float results
- SLJIT_TMP_DEST_VREG : a temporary register for vector results
+ SLJIT_TMP_DEST_REG : a temporary register for results, see the rules below
+ SLJIT_TMP_DEST_FREG : a temporary register for float results, see the rules below
+ SLJIT_TMP_DEST_VREG : a temporary register for vector results, see the rules below
+ SLJIT_TMP_OPT_REG : a temporary register which might not be defined, see the rules below
SLJIT_FUNC : calling convention attribute for both calling JIT from C and C calling back from JIT
SLJIT_W(number) : defining 64 bit constants on 64 bit architectures (platform independent helper)
SLJIT_F64_SECOND(reg) : provides the register index of the second 32 bit part of a 64 bit
floating point register when SLJIT_HAS_F64_AS_F32_PAIR returns non-zero
+
+ Temporary register rules (e.g. SLJIT_TMP_DEST_REG / SLJIT_TMP_OPT_REG):
+ Sljit tries to emit instructions without using any temporary registers whenever it is possible.
+ When a single temporary register is needed, it is always the "OPT" register. When two temporary
+ registers are needed, both the "DEST" and "OPT" are used. The x86-32 does not define an "OPT"
+ register, and handles all cases without an "OPT" register which requires an "OPT" register
+ on other architectures.
*/
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE) \
@@ -602,7 +609,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_LOCALS_OFFSET_BASE (8 * (sljit_s32)sizeof(sljit_sw))
#define SLJIT_PREF_SHIFT_REG SLJIT_R2
@@ -627,7 +633,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_LOCALS_OFFSET_BASE (4 * (sljit_s32)sizeof(sljit_sw))
#endif /* !_WIN64 */
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R1
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_PREF_SHIFT_REG SLJIT_R3
#define SLJIT_MASKED_SHIFT 1
@@ -644,7 +650,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_LOCALS_OFFSET_BASE 0
@@ -657,7 +663,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R0
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R1
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_LOCALS_OFFSET_BASE (2 * (sljit_s32)sizeof(sljit_sw))
#define SLJIT_MASKED_SHIFT 1
@@ -674,7 +680,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 18
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) || (defined _AIX)
#define SLJIT_LOCALS_OFFSET_BASE ((6 + 8) * (sljit_s32)sizeof(sljit_sw))
@@ -702,7 +708,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_TEMPORARY_REGISTERS 5
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 3
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_MASKED_SHIFT 1
#define SLJIT_MASKED_SHIFT32 1
@@ -721,7 +727,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_SAVED_VECTOR_REGISTERS 0
#define SLJIT_NUMBER_OF_TEMPORARY_VECTOR_REGISTERS 2
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_TMP_DEST_VREG SLJIT_TMP_VR0
#define SLJIT_LOCALS_OFFSET_BASE 0
@@ -759,8 +765,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_FLOAT_REGISTERS 15
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 8
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 1
-#define SLJIT_TMP_DEST_REG SLJIT_TMP_R0
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R2
+#define SLJIT_TMP_DEST_REG SLJIT_TMP_R2
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R1
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_LOCALS_OFFSET_BASE SLJIT_S390X_DEFAULT_STACK_FRAME_SIZE
#define SLJIT_MASKED_SHIFT 1
@@ -776,7 +782,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 12
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 2
#define SLJIT_TMP_DEST_REG SLJIT_TMP_R1
-#define SLJIT_TMP_MEM_REG SLJIT_TMP_R1
+#define SLJIT_TMP_OPT_REG SLJIT_TMP_R0
#define SLJIT_TMP_DEST_FREG SLJIT_TMP_FR0
#define SLJIT_LOCALS_OFFSET_BASE 0
#define SLJIT_MASKED_SHIFT 1
@@ -793,7 +799,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#define SLJIT_NUMBER_OF_SAVED_FLOAT_REGISTERS 0
#define SLJIT_NUMBER_OF_TEMPORARY_FLOAT_REGISTERS 0
#define SLJIT_TMP_DEST_REG 0
-#define SLJIT_TMP_MEM_REG 0
#define SLJIT_TMP_DEST_FREG 0
#define SLJIT_LOCALS_OFFSET_BASE 0
@@ -965,6 +970,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_sw sljit_exec_offset(void *code);
#endif /* !SLJIT_COMPILE_ASSERT */
+#ifndef SLJIT_FALLTHROUGH
+
+#if defined(__cplusplus) && __cplusplus >= 202002L && \
+ defined(__has_cpp_attribute)
+/* Standards-compatible C++ variant. */
+#if __has_cpp_attribute(fallthrough)
+#define SLJIT_FALLTHROUGH [[fallthrough]];
+#endif
+#elif !defined(__cplusplus) && \
+ defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L && \
+ defined(__has_c_attribute)
+/* Standards-compatible C variant. */
+#if __has_c_attribute(fallthrough)
+#define SLJIT_FALLTHROUGH [[fallthrough]];
+#endif
+#elif ((defined(__clang__) && __clang_major__ >= 10) || \
+ (defined(__GNUC__) && __GNUC__ >= 7)) && \
+ defined(__has_attribute)
+/* Clang and GCC syntax. Rule out old versions because apparently Clang at
+ least has a broken implementation of __has_attribute. */
+#if __has_attribute(fallthrough)
+#define SLJIT_FALLTHROUGH __attribute__((fallthrough));
+#endif
+#endif
+
+#ifndef SLJIT_FALLTHROUGH
+#define SLJIT_FALLTHROUGH
+#endif
+
+#endif /* !SLJIT_FALLTHROUGH */
+
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.c
index 6b2d5564c75..633e794b3bf 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.c
@@ -95,17 +95,12 @@
#define VARIABLE_FLAG_SHIFT (10)
/* All variable flags are even. */
#define VARIABLE_FLAG_MASK (0x3e << VARIABLE_FLAG_SHIFT)
+#define ALL_STATUS_FLAGS_MASK (VARIABLE_FLAG_MASK | SLJIT_SET_Z)
#define GET_FLAG_TYPE(op) ((op) >> VARIABLE_FLAG_SHIFT)
#define GET_FLAG_TYPE_MASK(op) (((op) >> VARIABLE_FLAG_SHIFT) & 0x3e)
-
-#define GET_OPCODE(op) \
- ((op) & 0xff)
-
-#define HAS_FLAGS(op) \
- ((op) & (SLJIT_SET_Z | VARIABLE_FLAG_MASK))
-
-#define GET_ALL_FLAGS(op) \
- ((op) & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK))
+#define GET_OPCODE(op) ((op) & 0xff)
+#define HAS_FLAGS(op) ((op) & ALL_STATUS_FLAGS_MASK)
+#define GET_ALL_FLAGS(op) ((op) & (SLJIT_32 | ALL_STATUS_FLAGS_MASK))
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
#define TYPE_CAST_NEEDED(op) \
@@ -155,10 +150,22 @@
#define SLJIT_SIMD_TYPE_MASK(m) ((sljit_s32)0xff000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))
#define SLJIT_SIMD_TYPE_MASK2(m) ((sljit_s32)0xc0000fff & ~(SLJIT_SIMD_FLOAT | SLJIT_SIMD_TEST | (m)))
-/* Jump flags. */
+/* Label definitions. */
+
+#define SLJIT_LABEL_ALIGNED ((~(sljit_uw)0) - 1)
+
+struct sljit_extended_label {
+ struct sljit_label label;
+ sljit_uw index;
+ sljit_uw data;
+};
+
+/* Jump definitions. */
+
+/* Jump flag bits. */
#define JUMP_ADDR 0x1
#define JUMP_MOV_ADDR 0x2
-/* SLJIT_REWRITABLE_JUMP is 0x1000. */
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
# define PATCH_MB 0x04
@@ -172,14 +179,15 @@
# define JUMP_MAX_SIZE ((sljit_uw)5)
# define CJUMP_MAX_SIZE ((sljit_uw)6)
#endif /* SLJIT_CONFIG_X86_64 */
-# define TYPE_SHIFT 13
+# define TYPE_SHIFT 17
#if (defined SLJIT_DEBUG && SLJIT_DEBUG)
-/* Bits 7..12 is for debug jump size, SLJIT_REWRITABLE_JUMP is 0x1000 */
-# define JUMP_SIZE_SHIFT 7
+/* Bits 7..15 is for debug jump size, SLJIT_REWRITABLE_JUMP is 0x10000 */
+# define JUMP_SIZE_SHIFT 8
#endif /* SLJIT_DEBUG */
#endif /* SLJIT_CONFIG_X86 */
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6) || (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
# define IS_BL 0x04
# define PATCH_B 0x08
#endif /* SLJIT_CONFIG_ARM_V6 || SLJIT_CONFIG_ARM_V7 */
@@ -194,8 +202,11 @@
#endif /* SLJIT_CONFIG_ARM_V7 */
#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
# define IS_COND 0x04
# define IS_BL 0x08
+ /* mov_addr does not use IS_BL */
+# define IS_ABS IS_BL
/* conditional + imm8 */
# define PATCH_TYPE1 0x10
/* conditional + imm20 */
@@ -214,6 +225,7 @@
#endif /* SLJIT_CONFIG_ARM_THUMB2 */
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64)
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
# define IS_COND 0x004
# define IS_CBZ 0x008
# define IS_BL 0x010
@@ -227,6 +239,7 @@
#endif /* SLJIT_CONFIG_ARM_64 */
#if (defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
# define IS_COND 0x004
# define IS_CALL 0x008
# define PATCH_B 0x010
@@ -243,6 +256,7 @@
#endif /* SLJIT_CONFIG_PPC */
#if (defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS)
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
# define IS_MOVABLE 0x004
# define IS_JAL 0x008
# define IS_CALL 0x010
@@ -270,26 +284,36 @@
#endif /* SLJIT_CONFIG_MIPS */
#if (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
-# define IS_COND 0x004
-# define IS_CALL 0x008
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
+# define IS_COND 0x0004
+# define IS_CALL 0x0008
-# define PATCH_B 0x010
-# define PATCH_J 0x020
+# define IS_COND16 0x0010
+# define PATCH_B 0x0020
+# define PATCH_J 0x0040
+# define PATCH_16 0x0080
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-# define PATCH_REL32 0x040
-# define PATCH_ABS32 0x080
-# define PATCH_ABS44 0x100
-# define PATCH_ABS52 0x200
+# define PATCH_REL32 0x0100
+# define PATCH_ABS32 0x0200
+# define PATCH_ABS44 0x0400
+# define PATCH_ABS52 0x0800
# define JUMP_SIZE_SHIFT 58
-# define JUMP_MAX_SIZE ((sljit_uw)6)
+# define JUMP_MAX_SIZE ((sljit_uw)12)
#else /* !SLJIT_CONFIG_RISCV_64 */
# define JUMP_SIZE_SHIFT 26
-# define JUMP_MAX_SIZE ((sljit_uw)2)
+# define JUMP_MAX_SIZE ((sljit_uw)4)
#endif /* SLJIT_CONFIG_RISCV_64 */
#endif /* SLJIT_CONFIG_RISCV */
+#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
+# define PATCH_POOL 0x004
+# define PATCH_IMM32 0x008
+#endif /* SLJIT_CONFIG_S390X */
+
#if (defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
+/* SLJIT_REWRITABLE_JUMP is 0x10000. */
# define IS_COND 0x004
# define IS_CALL 0x008
@@ -303,6 +327,7 @@
# define JUMP_MAX_SIZE ((sljit_uw)4)
#endif /* SLJIT_CONFIG_LOONGARCH */
+
/* Stack management. */
#define GET_SAVED_REGISTERS_SIZE(scratches, saveds, extra) \
@@ -451,12 +476,12 @@
/* Public functions */
/* --------------------------------------------------------------------- */
-#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
+#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
#define SLJIT_NEEDS_COMPILER_INIT 1
static sljit_s32 compiler_initialized = 0;
/* A thread safe initialization. */
static void init_compiler(void);
-#endif /* SLJIT_CONFIG_X86 */
+#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_RISCV */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allocator_data)
{
@@ -475,8 +500,12 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler* sljit_create_compiler(void *allo
&& (sizeof(sljit_sw) == 4 || sizeof(sljit_sw) == 8)
&& (sizeof(sljit_uw) == sizeof(sljit_sw)),
invalid_integer_types);
- SLJIT_COMPILE_ASSERT(SLJIT_REWRITABLE_JUMP != SLJIT_32,
- rewritable_jump_and_single_op_must_not_be_the_same);
+ SLJIT_COMPILE_ASSERT((SLJIT_REWRITABLE_JUMP & SLJIT_32) == 0
+ && (ALL_STATUS_FLAGS_MASK & SLJIT_32) == 0
+ && (SLJIT_REWRITABLE_JUMP & ALL_STATUS_FLAGS_MASK) == 0,
+ rewritable_jump_and_status_flag_bits_and_sljit_32_must_not_have_common_bits);
+ SLJIT_COMPILE_ASSERT((VARIABLE_FLAG_MASK & SLJIT_SET_Z) == 0,
+ rewritable_jump_and_status_flag_bits_must_not_have_common_bits);
SLJIT_COMPILE_ASSERT(!(SLJIT_EQUAL & 0x1) && !(SLJIT_LESS & 0x1) && !(SLJIT_F_EQUAL & 0x1) && !(SLJIT_JUMP & 0x1),
conditional_flags_must_be_even_numbers);
@@ -615,8 +644,8 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_target(struct sljit_jump *jump, sljit_uw
}
}
-#define SLJIT_CURRENT_FLAGS_ALL \
- (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE)
+#define SLJIT_CURRENT_FLAGS_ALL (SLJIT_CURRENT_FLAGS_32 | SLJIT_CURRENT_FLAGS_ADD \
+ | SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE | SLJIT_CURRENT_FLAGS_OP2CMPZ)
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *compiler, sljit_s32 current_flags)
{
@@ -624,12 +653,18 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_current_flags(struct sljit_compiler *com
SLJIT_UNUSED_ARG(current_flags);
#if (defined SLJIT_HAS_STATUS_FLAGS_STATE && SLJIT_HAS_STATUS_FLAGS_STATE)
+#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
+ if (current_flags & SLJIT_CURRENT_FLAGS_OP2CMPZ) {
+ current_flags |= SLJIT_SET_Z;
+ }
+#endif /* SLJIT_CONFIG_S390X */
+
compiler->status_flags_state = current_flags;
#endif /* SLJIT_HAS_STATUS_FLAGS_STATE */
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
compiler->last_flags = 0;
- if ((current_flags & ~(VARIABLE_FLAG_MASK | SLJIT_SET_Z | SLJIT_CURRENT_FLAGS_ALL)) == 0) {
+ if ((current_flags & ~(ALL_STATUS_FLAGS_MASK | SLJIT_CURRENT_FLAGS_ALL)) == 0) {
compiler->last_flags = GET_FLAG_TYPE(current_flags) | (current_flags & (SLJIT_32 | SLJIT_SET_Z));
}
#endif /* SLJIT_ARGUMENT_CHECKS */
@@ -826,22 +861,34 @@ static SLJIT_INLINE void set_label(struct sljit_label *label, struct sljit_compi
label->next = NULL;
label->u.index = compiler->label_count++;
label->size = compiler->size;
+
if (compiler->last_label != NULL)
compiler->last_label->next = label;
else
compiler->labels = label;
+
compiler->last_label = label;
}
+static SLJIT_INLINE void set_extended_label(struct sljit_extended_label *ext_label, struct sljit_compiler *compiler, sljit_uw type, sljit_uw data)
+{
+ set_label(&ext_label->label, compiler);
+ ext_label->index = ext_label->label.u.index;
+ ext_label->label.u.index = type;
+ ext_label->data = data;
+}
+
static SLJIT_INLINE void set_jump(struct sljit_jump *jump, struct sljit_compiler *compiler, sljit_u32 flags)
{
jump->next = NULL;
jump->flags = flags;
jump->u.label = NULL;
+
if (compiler->last_jump != NULL)
compiler->last_jump->next = jump;
else
compiler->jumps = jump;
+
compiler->last_jump = jump;
}
@@ -1318,6 +1365,10 @@ static const char* call_arg_names[] = {
"void", "w", "32", "p", "f64", "f32"
};
+static const char* op_addr_types[] = {
+ "mov_addr", "mov_abs_addr", "add_abs_addr"
+};
+
#endif /* SLJIT_VERBOSE */
/* --------------------------------------------------------------------- */
@@ -1328,18 +1379,21 @@ static const char* call_arg_names[] = {
|| (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
#define SLJIT_SKIP_CHECKS(compiler) (compiler)->skip_checks = 1
-#define SLJIT_CHECK_OPCODE(op, flags) ((op) & ~(SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK | (flags)))
+#define SLJIT_CHECK_OPCODE(op, flags) ((op) & ~(SLJIT_32 | ALL_STATUS_FLAGS_MASK | (flags)))
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler)
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
struct sljit_jump *jump;
#endif /* SLJIT_ARGUMENT_CHECKS */
SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(options);
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(compiler->size > 0);
+ CHECK_ARGUMENT((options & ~(SLJIT_GENERATE_CODE_BUFFER | SLJIT_GENERATE_CODE_NO_CONTEXT)) == 0);
+
jump = compiler->jumps;
while (jump) {
/* All jumps have target. */
@@ -1643,11 +1697,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op1(struct sljit_compiler
case SLJIT_REV_U32:
case SLJIT_REV_S32:
/* Nothing allowed */
- CHECK_ARGUMENT(!(op & (SLJIT_32 | SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & (SLJIT_32 | ALL_STATUS_FLAGS_MASK)));
break;
default:
/* Only SLJIT_32 is allowed. */
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));
break;
}
@@ -1679,8 +1733,8 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_load(struct sljit_
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_ATOMIC));
- CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z | VARIABLE_FLAG_MASK) >= SLJIT_MOV
- && SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | SLJIT_SET_Z | VARIABLE_FLAG_MASK) <= SLJIT_MOV_P);
+ CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | ALL_STATUS_FLAGS_MASK) >= SLJIT_MOV
+ && SLJIT_CHECK_OPCODE(op, SLJIT_ATOMIC_TEST | SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS | ALL_STATUS_FLAGS_MASK) <= SLJIT_MOV_P);
CHECK_ARGUMENT((op & (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS)) != (SLJIT_ATOMIC_USE_CAS | SLJIT_ATOMIC_USE_LS));
/* All arguments must be valid registers. */
@@ -1778,19 +1832,10 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_atomic_store(struct sljit
CHECK_RETURN_OK;
}
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,
- sljit_s32 dst, sljit_sw dstw,
- sljit_s32 src1, sljit_sw src1w,
- sljit_s32 src2, sljit_sw src2w)
-{
- if (SLJIT_UNLIKELY(compiler->skip_checks)) {
- compiler->skip_checks = 0;
- CHECK_RETURN_OK;
- }
-
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ROTR);
+static sljit_s32 check_sljit_emit_op2_operation(struct sljit_compiler *compiler, sljit_s32 op)
+{
switch (GET_OPCODE(op)) {
case SLJIT_AND:
case SLJIT_OR:
@@ -1801,39 +1846,49 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler
case SLJIT_MLSHR:
case SLJIT_ASHR:
case SLJIT_MASHR:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK));
- break;
+ return !(op & VARIABLE_FLAG_MASK);
case SLJIT_MUL:
- CHECK_ARGUMENT(!(op & SLJIT_SET_Z));
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
- break;
+ return !(op & SLJIT_SET_Z) && (!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
case SLJIT_ADD:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
+ return !(op & VARIABLE_FLAG_MASK)
|| GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
- || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW);
- break;
+ || GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
case SLJIT_SUB:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
+ return !(op & VARIABLE_FLAG_MASK)
|| (GET_FLAG_TYPE(op) >= SLJIT_LESS && GET_FLAG_TYPE(op) <= SLJIT_OVERFLOW)
- || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
- break;
+ || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY);
case SLJIT_ADDC:
case SLJIT_SUBC:
- CHECK_ARGUMENT(!(op & VARIABLE_FLAG_MASK)
- || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
- CHECK_ARGUMENT((compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY));
- CHECK_ARGUMENT((op & SLJIT_32) == (compiler->last_flags & SLJIT_32));
+ return (!(op & VARIABLE_FLAG_MASK) || GET_FLAG_TYPE(op) == GET_FLAG_TYPE(SLJIT_SET_CARRY))
+ && (compiler->last_flags & 0xff) == GET_FLAG_TYPE(SLJIT_SET_CARRY)
+ && (op & SLJIT_32) == (compiler->last_flags & SLJIT_32);
break;
case SLJIT_ROTL:
case SLJIT_ROTR:
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
- break;
- default:
- SLJIT_UNREACHABLE();
- break;
+ return !(op & ALL_STATUS_FLAGS_MASK);
}
+ /* Operation type should be checked earlier. */
+ SLJIT_UNREACHABLE();
+ return 1;
+}
+
+#endif /* SLJIT_ARGUMENT_CHECKS */
+
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 unset,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ROTR);
+ CHECK_ARGUMENT(check_sljit_emit_op2_operation(compiler, op));
+
if (unset) {
CHECK_ARGUMENT(HAS_FLAGS(op));
} else {
@@ -1923,6 +1978,36 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_shift_into(struct sljit_c
CHECK_RETURN_OK;
}
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ SLJIT_UNUSED_ARG(shift_arg);
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT((op & ~SLJIT_SRC2_UNDEFINED) == (SLJIT_ADD | SLJIT_SHL_IMM));
+ FUNCTION_CHECK_DST(dst, dstw);
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+ compiler->last_flags = 0;
+#endif /* SLJIT_ARGUMENT_CHECKS */
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " %s.shl_imm%s ", op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE],
+ (op & SLJIT_SRC2_UNDEFINED) ? ".src2und" : "");
+
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src2, src2w);
+ fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", shift_arg);
+ }
+#endif /* SLJIT_VERBOSE */
+ CHECK_RETURN_OK;
+}
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -2005,12 +2090,12 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_custom(struct sljit_co
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
CHECK_ARGUMENT(size > 0 && size < 16);
-#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+#elif (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2) || (defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV)
CHECK_ARGUMENT((size == 2 && (((sljit_sw)instruction) & 0x1) == 0)
|| (size == 4 && (((sljit_sw)instruction) & 0x3) == 0));
#elif (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
CHECK_ARGUMENT(size == 2 || size == 4 || size == 6);
-#else /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_CONFIG_S390X */
+#else /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_THUMB2 && !SLJIT_CONFIG_RISCV && !SLJIT_CONFIG_S390X */
CHECK_ARGUMENT(size == 4 && (((sljit_sw)instruction) & 0x3) == 0);
#endif /* SLJIT_CONFIG_X86 */
@@ -2039,7 +2124,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1(struct sljit_compile
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_MOV_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_ABS_F64);
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));
FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
#endif /* SLJIT_ARGUMENT_CHECKS */
@@ -2110,7 +2195,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_sw_from_f64(str
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));
FUNCTION_FCHECK(src, srcw, op & SLJIT_32);
FUNCTION_CHECK_DST(dst, dstw);
#endif /* SLJIT_ARGUMENT_CHECKS */
@@ -2139,7 +2224,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop1_conv_f64_from_w(stru
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));
FUNCTION_CHECK_SRC(src, srcw);
FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
#endif /* SLJIT_ARGUMENT_CHECKS */
@@ -2170,7 +2255,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fop2(struct sljit_compile
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_ADD_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_DIV_F64);
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));
FUNCTION_FCHECK(src1, src1w, op & SLJIT_32);
FUNCTION_FCHECK(src2, src2w, op & SLJIT_32);
FUNCTION_FCHECK(dst, dstw, op & SLJIT_32);
@@ -2269,7 +2354,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcopy(struct sljit_compil
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(sljit_has_cpu_feature(SLJIT_HAS_FPU));
CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, 0) >= SLJIT_COPY_TO_F64 && SLJIT_CHECK_OPCODE(op, 0) <= SLJIT_COPY_FROM_F64);
- CHECK_ARGUMENT(!(op & (SLJIT_SET_Z | VARIABLE_FLAG_MASK)));
+ CHECK_ARGUMENT(!(op & ALL_STATUS_FLAGS_MASK));
CHECK_ARGUMENT(FUNCTION_CHECK_IS_FREG(freg, op & SLJIT_32));
#if (defined SLJIT_64BIT_ARCHITECTURE && SLJIT_64BIT_ARCHITECTURE)
@@ -2341,6 +2426,37 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_label(struct sljit_compil
CHECK_RETURN_OK;
}
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ SLJIT_UNUSED_ARG(compiler);
+ SLJIT_UNUSED_ARG(buffers);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(alignment >= SLJIT_LABEL_ALIGN_1 && alignment <= SLJIT_LABEL_ALIGN_16);
+ compiler->last_flags = 0;
+#endif /* SLJIT_ARGUMENT_CHECKS */
+
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, "label.al%d:%s", 1 << alignment, buffers == NULL ? "\n" : " [");
+
+ if (buffers != NULL) {
+ fprintf(compiler->verbose, "%ld", (long int)buffers->size);
+ buffers = buffers->next;
+
+ while (buffers != NULL) {
+ fprintf(compiler->verbose, ", %ld", (long int)buffers->size);
+ buffers = buffers->next;
+ }
+
+ fprintf(compiler->verbose, "]\n");
+ }
+ }
+#endif /* SLJIT_VERBOSE */
+ CHECK_RETURN_OK;
+}
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
|| (defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM)
@@ -2427,6 +2543,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_cmp(struct sljit_compiler
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2, sljit_sw src2w)
{
+ if (SLJIT_UNLIKELY(compiler->skip_checks)) {
+ compiler->skip_checks = 0;
+ CHECK_RETURN_OK;
+ }
+
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
CHECK_ARGUMENT(!(type & ~(0xff | SLJIT_REWRITABLE_JUMP | SLJIT_32)));
CHECK_ARGUMENT((type & 0xff) >= SLJIT_EQUAL && (type & 0xff) <= SLJIT_SIG_LESS_EQUAL);
@@ -2472,6 +2593,40 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_fcmp(struct sljit_compile
CHECK_RETURN_OK;
}
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ SLJIT_COMPILE_ASSERT((SLJIT_JUMP_IF_ZERO == SLJIT_SET_Z) && (SLJIT_JUMP_IF_NON_ZERO == 0),
+ incorrect_values_for_sljit_jump_zero_or_non_zero);
+
+#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(SLJIT_CHECK_OPCODE(op, SLJIT_REWRITABLE_JUMP) >= SLJIT_ADD && SLJIT_CHECK_OPCODE(op, SLJIT_REWRITABLE_JUMP) <= SLJIT_ROTR);
+ /* Not all opcodes allow setting zero flags. */
+ CHECK_ARGUMENT(check_sljit_emit_op2_operation(compiler, ((op | SLJIT_SET_Z) & ~SLJIT_REWRITABLE_JUMP)));
+ FUNCTION_CHECK_DST(dst, dstw);
+ FUNCTION_CHECK_SRC(src1, src1w);
+ FUNCTION_CHECK_SRC(src2, src2w);
+ compiler->last_flags = GET_FLAG_TYPE(op) | (op & SLJIT_32);
+#endif /* SLJIT_ARGUMENT_CHECKS */
+#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
+ if (SLJIT_UNLIKELY(!!compiler->verbose)) {
+ fprintf(compiler->verbose, " cmp%sz.%s%s%s%s%s ", (op & SLJIT_JUMP_IF_ZERO) ? "" : "n",
+ op2_names[GET_OPCODE(op) - SLJIT_OP2_BASE], !(op & SLJIT_32) ? "" : "32",
+ !(op & VARIABLE_FLAG_MASK) ? "" : ".", !(op & VARIABLE_FLAG_MASK) ? "" : jump_names[GET_FLAG_TYPE(op & ~SLJIT_REWRITABLE_JUMP)],
+ !(op & SLJIT_REWRITABLE_JUMP) ? "" : ".r");
+ sljit_verbose_param(compiler, dst, dstw);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src1, src1w);
+ fprintf(compiler->verbose, ", ");
+ sljit_verbose_param(compiler, src2, src2w);
+ fprintf(compiler->verbose, "\n");
+ }
+#endif /* SLJIT_VERBOSE */
+ CHECK_RETURN_OK;
+}
+
static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 src, sljit_sw srcw)
{
@@ -2578,27 +2733,30 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_select(struct sljit_compi
sljit_s32 src2_reg)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
- sljit_s32 cond = type & ~SLJIT_32;
-
- CHECK_ARGUMENT(cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL);
-
+ sljit_s32 cond = type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT);
+ CHECK_ARGUMENT((type & SLJIT_COMPARE_SELECT) ? (cond >= SLJIT_LESS && cond <= SLJIT_SET_SIG_LESS_EQUAL)
+ : (cond >= SLJIT_EQUAL && cond <= SLJIT_ORDERED_LESS_EQUAL));
CHECK_ARGUMENT(compiler->scratches != -1 && compiler->saveds != -1);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(dst_reg));
FUNCTION_CHECK_SRC(src1, src1w);
CHECK_ARGUMENT(FUNCTION_CHECK_IS_REG(src2_reg));
- if (cond <= SLJIT_NOT_ZERO)
- CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
- else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
- CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
- compiler->last_flags = 0;
+ if (!(type & SLJIT_COMPARE_SELECT)) {
+ if (cond <= SLJIT_NOT_ZERO)
+ CHECK_ARGUMENT(compiler->last_flags & SLJIT_SET_Z);
+ else if ((compiler->last_flags & 0xff) == SLJIT_CARRY) {
+ CHECK_ARGUMENT((type & 0xfe) == SLJIT_CARRY);
+ compiler->last_flags = 0;
+ } else
+ CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)
+ || CHECK_UNORDERED(cond, compiler->last_flags));
} else
- CHECK_ARGUMENT((cond & 0xfe) == (compiler->last_flags & 0xff)
- || CHECK_UNORDERED(cond, compiler->last_flags));
+ compiler->last_flags = 0;
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " select%s %s, ",
+ fprintf(compiler->verbose, " %sselect%s %s, ",
+ !(type & SLJIT_COMPARE_SELECT) ? "" : "cmp_",
!(type & SLJIT_32) ? "" : "32",
jump_names[type & ~SLJIT_32]);
sljit_verbose_reg(compiler, dst_reg);
@@ -2680,7 +2838,7 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler
case SLJIT_MOV_P:
case SLJIT_MOV:
allowed_flags |= SLJIT_MEM_ALIGNED_32;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_MOV_U32:
case SLJIT_MOV_S32:
case SLJIT_MOV32:
@@ -2714,11 +2872,11 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mem(struct sljit_compiler
!(type & SLJIT_32) ? "" : "32", op1_types[(type & 0xff) - SLJIT_OP1_BASE]);
if (type & SLJIT_MEM_UNALIGNED)
- printf(".unal");
+ fprintf(compiler->verbose, ".unal");
else if (type & SLJIT_MEM_ALIGNED_16)
- printf(".al16");
+ fprintf(compiler->verbose, ".al16");
else if (type & SLJIT_MEM_ALIGNED_32)
- printf(".al32");
+ fprintf(compiler->verbose, ".al32");
if (reg & REG_PAIR_MASK) {
fprintf(compiler->verbose, " {");
@@ -3176,16 +3334,21 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_get_local_base(struct sljit_co
CHECK_RETURN_OK;
}
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
SLJIT_UNUSED_ARG(init_value);
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(op == SLJIT_MOV || op == SLJIT_MOV_S32
+ || op == SLJIT_MOV32 || (op | SLJIT_32) == SLJIT_MOV32_U8);
FUNCTION_CHECK_DST(dst, dstw);
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " const ");
+ fprintf(compiler->verbose, " const%s%s ",
+ !(op & SLJIT_32) ? "" : "32", op1_types[GET_OPCODE(op) - SLJIT_OP1_BASE]);
sljit_verbose_param(compiler, dst, dstw);
fprintf(compiler->verbose, ", #%" SLJIT_PRINT_D "d\n", init_value);
}
@@ -3193,14 +3356,16 @@ static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_const(struct sljit_compil
CHECK_RETURN_OK;
}
-static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+static SLJIT_INLINE CHECK_RETURN_TYPE check_sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS)
+ CHECK_ARGUMENT(op == SLJIT_MOV_ADDR || op == SLJIT_MOV_ABS_ADDR || op == SLJIT_ADD_ABS_ADDR);
FUNCTION_CHECK_DST(dst, dstw);
#endif /* SLJIT_ARGUMENT_CHECKS */
#if (defined SLJIT_VERBOSE && SLJIT_VERBOSE)
if (SLJIT_UNLIKELY(!!compiler->verbose)) {
- fprintf(compiler->verbose, " mov_addr ");
+ fprintf(compiler->verbose, " %s ", op_addr_types[op]);
sljit_verbose_param(compiler, dst, dstw);
fprintf(compiler->verbose, "\n");
}
@@ -3276,6 +3441,14 @@ static sljit_s32 sljit_emit_fmem_unaligned(struct sljit_compiler *compiler, slji
#endif /* (!SLJIT_CONFIG_MIPS || SLJIT_MIPS_REV >= 6) && !SLJIT_CONFIG_ARM */
+static void sljit_reset_read_only_buffers(struct sljit_read_only_buffer *buffers)
+{
+ while (buffers != NULL) {
+ buffers->u.label = NULL;
+ buffers = buffers->next;
+ }
+}
+
/* CPU description section */
#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE)
@@ -3501,6 +3674,49 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compile
return sljit_emit_jump(compiler, type);
}
+#if !(defined SLJIT_CONFIG_RISCV && SLJIT_CONFIG_RISCV) \
+ && !(defined SLJIT_CONFIG_MIPS && SLJIT_CONFIG_MIPS) \
+ && !(defined SLJIT_CONFIG_LOONGARCH && SLJIT_CONFIG_LOONGARCH)
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_op2cmpz(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+
+ SLJIT_SKIP_CHECKS(compiler);
+ PTR_FAIL_IF(sljit_emit_op2(compiler, ((op | SLJIT_SET_Z) & ~SLJIT_REWRITABLE_JUMP), dst, dstw, src1, src1w, src2, src2w));
+
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_jump(compiler, ((op & SLJIT_JUMP_IF_ZERO) ? SLJIT_ZERO : SLJIT_NOT_ZERO) | (op & SLJIT_REWRITABLE_JUMP));
+}
+
+#else /* SLJIT_CONFIG_RISCV || SLJIT_CONFIG_MIPS || SLJIT_CONFIG_LOONGARCH */
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w)
+{
+ sljit_s32 reg;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_op2cmpz(compiler, op, dst, dstw, src1, src1w, src2, src2w));
+
+ SLJIT_SKIP_CHECKS(compiler);
+ PTR_FAIL_IF(sljit_emit_op2(compiler, (op & ~(SLJIT_SET_Z | SLJIT_REWRITABLE_JUMP)), dst, dstw, src1, src1w, src2, src2w));
+
+ /* When dst is a memory operand, its value is stored in SLJIT_TMP_DEST_FREG. */
+ reg = FAST_IS_REG(dst) ? dst : SLJIT_TMP_DEST_REG;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_cmp(compiler, ((op & SLJIT_JUMP_IF_ZERO) ? SLJIT_ZERO : SLJIT_NOT_ZERO) | (op & (SLJIT_32 | SLJIT_REWRITABLE_JUMP)), reg, 0, SLJIT_IMM, 0);
+}
+
+#endif /* !SLJIT_CONFIG_RISCV && !SLJIT_CONFIG_MIPS && !SLJIT_CONFIG_LOONGARCH */
+
#if !(defined SLJIT_CONFIG_ARM && SLJIT_CONFIG_ARM) \
&& !(defined SLJIT_CONFIG_PPC && SLJIT_CONFIG_PPC)
@@ -3687,4 +3903,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
#endif /* !SLJIT_CONFIG_X86 && !SLJIT_CONFIG_ARM_64 */
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_read_only_buffer_start_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset)
+{
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + size), 0);
+ return SLJIT_ADD_EXEC_OFFSET(addr, -executable_offset);
+}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_read_only_buffer_end_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset)
+{
+ SLJIT_UNUSED_ARG(addr);
+ SLJIT_UNUSED_ARG(size);
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + size), 1);
+ SLJIT_CACHE_FLUSH((void*)addr, (void*)(addr + size));
+}
+
#endif /* !SLJIT_CONFIG_UNSUPPORTED */
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.h b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.h
index 60d34f15430..c5bf1287c39 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.h
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitLir.h
@@ -503,6 +503,16 @@ struct sljit_generate_code_buffer {
sljit_sw executable_offset;
};
+struct sljit_read_only_buffer {
+ struct sljit_read_only_buffer *next;
+ sljit_uw size;
+ /* Label can be replaced by address after sljit_generate_code. */
+ union {
+ struct sljit_label *label;
+ sljit_uw addr;
+ } u;
+};
+
struct sljit_compiler {
sljit_s32 error;
sljit_s32 options;
@@ -705,6 +715,12 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_compiler_verbose(struct sljit_compiler *comp
buffer which type is sljit_generate_code_buffer. */
#define SLJIT_GENERATE_CODE_BUFFER 0x1
+/* When SLJIT_INDIRECT_CALL is defined, no function context is
+created for the generated code (see sljit_set_function_context),
+so the returned pointer cannot be directly called from C code.
+The flag is ignored when SLJIT_INDIRECT_CALL is not defined. */
+#define SLJIT_GENERATE_CODE_NO_CONTEXT 0x2
+
/* Create executable code from the instruction stream. This is the final step
of the code generation, and no more instructions can be emitted after this call.
@@ -1450,6 +1466,24 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
sljit_s32 src2_reg,
sljit_s32 src3, sljit_sw src3w);
+/* The following options are used by sljit_emit_op2_shift. */
+
+/* The src2 argument is shifted left by an immedate value. */
+#define SLJIT_SHL_IMM (1 << 9)
+/* When src2 argument is a register, its value is undefined after the operation. */
+#define SLJIT_SRC2_UNDEFINED (1 << 10)
+
+/* Emits an addition operation, where the second argument is shifted by a value.
+
+ op must be SLJIT_ADD | SLJIT_SHL_IMM, where the immedate value is stored in shift_arg
+
+ Flags: - (may destroy flags) */
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg);
+
/* Starting index of opcodes for sljit_emit_op_src
and sljit_emit_op_dst. */
#define SLJIT_OP_SRC_DST_BASE 112
@@ -1629,8 +1663,53 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fcopy(struct sljit_compiler *compi
/* Label and jump instructions. */
+/* Emits a label which can be the target of jump / mov_addr instructions. */
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compiler *compiler);
+/* Alignment values for sljit_emit_aligned_label. */
+
+#define SLJIT_LABEL_ALIGN_1 0
+#define SLJIT_LABEL_ALIGN_2 1
+#define SLJIT_LABEL_ALIGN_4 2
+#define SLJIT_LABEL_ALIGN_8 3
+#define SLJIT_LABEL_ALIGN_16 4
+#define SLJIT_LABEL_ALIGN_W SLJIT_WORD_SHIFT
+#define SLJIT_LABEL_ALIGN_P SLJIT_POINTER_SHIFT
+
+/* Emits a label which address is aligned to a power of 2 value. When some
+ extra space needs to be added to align the label, that space is filled
+ with SLJIT_NOP instructions. These labels usually represent the end of a
+ compilation block, and a new function or some read-only data (e.g. a
+ jump table) follows it. In these typical cases the SLJIT_NOPs are never
+ executed.
+
+ Optionally, buffers for storing read-only data or code can be allocated
+ by this operation. The buffers are passed as a chain list, and a separate
+ memory area is allocated for each item in the list. All buffers are aligned
+ to SLJIT_NOP instruction size, and their starting address is returned as
+ as a label. The sljit_get_label_abs_addr function or the SLJIT_MOV_ABS_ADDR
+ operation can be used to get the real address. The label of the first buffer
+ is always the same as the returned label. The buffers are initially
+ initialized with SLJIT_NOP instructions. The alignment of the buffers can
+ be controlled by their starting address and sizes. If the starting address
+ is aligned to N, and size is also divisible by N, the next buffer is aligned
+ to N. I.e. if a buffer is 16 byte aligned, and its size is divisible by 4,
+ the next buffer is 4 byte aligned. Note: if a buffer is N (>=2) byte aligned,
+ it is also N/2 byte aligned.
+
+ align represents the alignment, and its value can
+ be specified by SLJIT_LABEL_* constants
+
+ buffers is a list of read-only buffers stored in a chain list.
+ After calling sljit_generate_code, these buffers can be
+ modified by sljit_read_only_buffer_start_writing() /
+ sljit_read_only_buffer_end_writing() functions
+
+ Note: the constant pool (if present) may be stored before the label. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers);
+
/* The SLJIT_FAST_CALL is a calling method for creating lightweight function
calls. This type of calls preserve the values of all registers and stack
frame. Unlike normal function calls, the enter and return operations must
@@ -1757,16 +1836,16 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
#define SLJIT_CALL_REG_ARG 39
/* The target can be changed during runtime (see: sljit_set_jump_addr). */
-#define SLJIT_REWRITABLE_JUMP 0x1000
+#define SLJIT_REWRITABLE_JUMP 0x10000
/* When this flag is passed, the execution of the current function ends and
the called function returns to the caller of the current function. The
stack usage is reduced before the call, but it is not necessarily reduced
to zero. In the latter case the compiler needs to allocate space for some
arguments and the return address must be stored on the stack as well. */
-#define SLJIT_CALL_RETURN 0x2000
+#define SLJIT_CALL_RETURN 0x20000
/* Emit a jump instruction. The destination is not set, only the type of the jump.
- type must be between SLJIT_EQUAL and SLJIT_FAST_CALL
+ type must be between SLJIT_JUMP and SLJIT_FAST_CALL
type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
Flags: does not modify flags. */
@@ -1780,31 +1859,56 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
Flags: destroy all flags. */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 arg_types);
-/* Basic arithmetic comparison. In most architectures it is implemented as
- a compare operation followed by a sljit_emit_jump. However some
- architectures (i.e: ARM64 or MIPS) may employ special optimizations
- here. It is suggested to use this comparison form when appropriate.
+/* Integer comparison operation. In most architectures it is implemented
+ as a compare (sljit_emit_op2u with SLJIT_SUB) operation followed by
+ an sljit_emit_jump. However, some architectures (e.g: ARM64 or RISCV)
+ may optimize the generated code further. It is suggested to use this
+ comparison form when appropriate.
type must be between SLJIT_EQUAL and SLJIT_SIG_LESS_EQUAL
- type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+ type can be combined (or'ed) with SLJIT_32 or SLJIT_REWRITABLE_JUMP
Flags: may destroy flags. */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2, sljit_sw src2w);
-/* Basic floating point comparison. In most architectures it is implemented as
- a SLJIT_CMP_F32/64 operation (setting appropriate flags) followed by a
- sljit_emit_jump. However some architectures (i.e: MIPS) may employ
- special optimizations here. It is suggested to use this comparison form
- when appropriate.
+/* Floating point comparison operation. In most architectures it is
+ implemented as a SLJIT_CMP_F32/64 operation (setting appropriate
+ flags) followed by a sljit_emit_jump. However, some architectures
+ (e.g: MIPS) may optimize the generated code further. It is suggested
+ to use this comparison form when appropriate.
type must be between SLJIT_F_EQUAL and SLJIT_ORDERED_LESS_EQUAL
- type can be combined (or'ed) with SLJIT_REWRITABLE_JUMP
+ type can be combined (or'ed) with SLJIT_32 or SLJIT_REWRITABLE_JUMP
+
Flags: destroy flags.
- Note: when an operand is NaN the behaviour depends on the comparison type. */
+ Note: when any operand is NaN the behaviour depends on the comparison type. */
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_fcmp(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2, sljit_sw src2w);
+/* The following flags are used by sljit_emit_op2cmpz(). */
+#define SLJIT_JUMP_IF_NON_ZERO 0
+#define SLJIT_JUMP_IF_ZERO SLJIT_SET_Z
+
+/* Perform an integer arithmetic operation, then its result is compared to
+ zero. In most architectures it is implemented as an sljit_emit_op2
+ followed by an sljit_emit_jump. However, some architectures (e.g: RISCV)
+ may optimize the generated code further. It is suggested to use this
+ operation form when appropriate (e.g. for loops with counters).
+
+ op must be an sljit_emit_op2 operation where zero flag can be set,
+ op can be combined with SLJIT_SET_* status flag setters except
+ SLJIT_SET_Z, SLJIT_REWRITABLE_JUMP or SLJIT_JUMP_IF_* option bits.
+
+ Note: SLJIT_JUMP_IF_NON_ZERO is the default operation if neither
+ SLJIT_JUMP_IF_ZERO or SLJIT_JUMP_IF_NON_ZERO is specified.
+ Flags: sets the variable flag depending on op argument, the
+ zero flag is undefined. */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op2cmpz(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w);
+
/* Set the destination of the jump to this label. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_label(struct sljit_jump *jump, struct sljit_label* label);
/* Set the destination address of the jump to this label. */
@@ -1831,7 +1935,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compi
/* Perform an operation using the conditional flags as the second argument.
Type must always be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL.
The value represented by the type is 1, if the condition represented
- by the type is fulfilled, and 0 otherwise.
+ by type is fulfilled, and 0 otherwise.
When op is SLJIT_MOV or SLJIT_MOV32:
Set dst to the value represented by the type (0 or 1).
@@ -1844,27 +1948,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
sljit_s32 dst, sljit_sw dstw,
sljit_s32 type);
+/* The following flags are used by sljit_emit_select(). */
+
+/* Compare src1 and src2_reg operands before executing select
+ (i.e. converts the select operation to a min/max operation). */
+#define SLJIT_COMPARE_SELECT SLJIT_SET_Z
+
/* Emit a conditional select instruction which moves src1 to dst_reg,
- if the condition is satisfied, or src2_reg to dst_reg otherwise.
+ if the conditional flag is set, or src2_reg to dst_reg otherwise.
+ The conditional flag should be set before executing the select
+ instruction unless SLJIT_COMPARE_SELECT is specified.
type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL
+ when SLJIT_COMPARE_SELECT option is NOT specified
+ type must be between SLJIT_LESS and SLJIT_SET_SIG_LESS_EQUAL
+ when SLJIT_COMPARE_SELECT option is specified
type can be combined (or'ed) with SLJIT_32 to move 32 bit
register values instead of word sized ones
+ type can be combined (or'ed) with SLJIT_COMPARE_SELECT
+ which compares src1 and src2_reg before executing the select
dst_reg and src2_reg must be valid registers
src1 must be valid operand
Note: if src1 is a memory operand, its value
- might be loaded even if the condition is false.
-
- Flags: - (does not modify flags) */
+ might be loaded even if the condition is false
+
+ Note: when SLJIT_COMPARE_SELECT is specified, the status flag
+ bits might not represent the result of a normal compare
+ operation, hence flags are not specified after the operation
+
+ Note: if sljit_has_cpu_feature(SLJIT_HAS_CMOV) returns with a non-zero value:
+ (a) conditional register move (dst_reg==src2_reg, src1 is register)
+ can be performed using a single instruction, except on RISCV,
+ where three instructions are needed
+ (b) conditional clearing (dst_reg==src2_reg, src1==SLJIT_IMM,
+ src1w==0) can be performed using a single instruction,
+ except on x86, where two instructions are needed
+
+ Flags:
+ When SLJIT_COMPARE_SELECT is NOT specified: - (does not modify flags)
+ When SLJIT_COMPARE_SELECT is specified: - (may destroy flags) */
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *compiler, sljit_s32 type,
sljit_s32 dst_reg,
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2_reg);
/* Emit a conditional floating point select instruction which moves
- src1 to dst_reg, if the condition is satisfied, or src2_reg to
- dst_reg otherwise.
+ src1 to dst_reg, if the conditional flag is set, or src2_reg to
+ dst_reg otherwise. The conditional flag should be set before
+ executing the select instruction.
type must be between SLJIT_EQUAL and SLJIT_ORDERED_LESS_EQUAL
type can be combined (or'ed) with SLJIT_32 to move 32 bit
@@ -2301,26 +2433,66 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
Flags: - (may destroy flags) */
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw offset);
-/* Store a value that can be changed runtime (see: sljit_get_const_addr / sljit_set_const)
+/* Store a value that can be changed at runtime. The constant
+ can be managed by sljit_get_const_addr and sljit_set_const.
+
+ op must be SLJIT_MOV, SLJIT_MOV32, SLJIT_MOV_S32,
+ SLJIT_MOV_U8, SLJIT_MOV32_U8
+
+ Note: when SLJIT_MOV_U8 is used, and dst is a register,
+ init_value supports a 9 bit signed value between [-256..255]
+
Flags: - (does not modify flags) */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value);
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value);
+
+/* Opcodes for sljit_emit_mov_addr. */
+
+/* The address is suitable for jump/call target. */
+#define SLJIT_MOV_ADDR 0
+/* The address is suitable for reading memory. */
+#define SLJIT_MOV_ABS_ADDR 1
+/* Add absolute address. */
+#define SLJIT_ADD_ABS_ADDR 2
/* Store the value of a label (see: sljit_set_label / sljit_set_target)
Flags: - (does not modify flags) */
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw);
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw);
+
+/* Returns the address of a label after sljit_generate_code is called, and
+ before the compiler is freed by sljit_free_compiler. It is recommended
+ to save these addresses elsewhere before sljit_free_compiler is called.
+
+ The address returned by sljit_get_label_addr is suitable for a jump/call
+ target, and the address returned by sljit_get_label_abs_addr is suitable
+ for reading memory. */
-/* Provides the address of label, jump and const instructions after sljit_generate_code
- is called. The returned value is unspecified before the sljit_generate_code call.
- Since these structures are freed by sljit_free_compiler, the addresses must be
- preserved by the user program elsewere. */
static SLJIT_INLINE sljit_uw sljit_get_label_addr(struct sljit_label *label) { return label->u.addr; }
+#if (defined SLJIT_CONFIG_ARM_THUMB2 && SLJIT_CONFIG_ARM_THUMB2)
+static SLJIT_INLINE sljit_uw sljit_get_label_abs_addr(struct sljit_label *label) { return label->u.addr & ~(sljit_uw)1; }
+#else /* !SLJIT_CONFIG_ARM_THUMB2 */
+static SLJIT_INLINE sljit_uw sljit_get_label_abs_addr(struct sljit_label *label) { return label->u.addr; }
+#endif /* SLJIT_CONFIG_ARM_THUMB2 */
+
+/* Returns the address of jump and const instructions after sljit_generate_code
+ is called, and before the compiler is freed by sljit_free_compiler. It is
+ recommended to save these addresses elsewhere before sljit_free_compiler is called. */
+
static SLJIT_INLINE sljit_uw sljit_get_jump_addr(struct sljit_jump *jump) { return jump->addr; }
static SLJIT_INLINE sljit_uw sljit_get_const_addr(struct sljit_const *const_) { return const_->addr; }
/* Only the address and executable offset are required to perform dynamic
code modifications. See sljit_get_executable_offset function. */
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset);
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset);
+/* The op opcode must be set to the same value that was passed to sljit_emit_const. */
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset);
+
+/* Only a single buffer is writable at a time, so sljit_read_only_buffer_end_writing()
+ must be called before sljit_read_only_buffer_start_writing() is called again. */
+SLJIT_API_FUNC_ATTRIBUTE void* sljit_read_only_buffer_start_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset);
+SLJIT_API_FUNC_ATTRIBUTE void sljit_read_only_buffer_end_writing(sljit_uw addr, sljit_uw size, sljit_sw executable_offset);
/* --------------------------------------------------------------------- */
/* CPU specific functions */
@@ -2369,13 +2541,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
/* Flags were set by an ADD or ADDC operations. */
#define SLJIT_CURRENT_FLAGS_ADD 0x01
-/* Flags were set by a SUB, SUBC, or NEG operation. */
+/* Flags were set by a SUB or SUBC operation. */
#define SLJIT_CURRENT_FLAGS_SUB 0x02
/* Flags were set by sljit_emit_op2u with SLJIT_SUB opcode.
Must be combined with SLJIT_CURRENT_FLAGS_SUB. */
#define SLJIT_CURRENT_FLAGS_COMPARE 0x04
+/* Flags were set by sljit_emit_op2cmpz operation. */
+#define SLJIT_CURRENT_FLAGS_OP2CMPZ 0x08
+
/* Define the currently available CPU status flags. It is usually used after
an sljit_emit_label or sljit_emit_op_custom operations to define which CPU
status flags are available.
@@ -2405,10 +2580,14 @@ static SLJIT_INLINE struct sljit_const *sljit_get_next_const(struct sljit_const
/* A number starting from 0 is assigned to each label, which
represents its creation index. The first label created by the
-compiler has index 0, the second has index 1, the third has
-index 2, and so on. The returned value is unspecified after
-sljit_generate_code() is called. */
-static SLJIT_INLINE sljit_uw sljit_get_label_index(struct sljit_label *label) { return label->u.index; }
+compiler has index 0, the second one has index 1, the third one
+has index 2, and so on. The returned value is unspecified after
+sljit_generate_code() is called.
+
+It is recommended to use this function to get the creation index
+of a label, since sljit_emit_label() may return with the last label,
+if no code is generated since the last sljit_emit_label() call. */
+SLJIT_API_FUNC_ATTRIBUTE sljit_uw sljit_get_label_index(struct sljit_label *label);
/* The sljit_jump_has_label() and sljit_jump_has_target() functions
returns non-zero value if a label or target is set for the jump
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_32.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_32.c
index 327dc824efc..16ef39940c5 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_32.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_32.c
@@ -93,7 +93,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1)
#define VN(vn) (((sljit_ins)freg_map[vn] << 16) | ((sljit_ins)freg_ebit_map[vn] << 7))
/* --------------------------------------------------------------------- */
-/* Instrucion forms */
+/* Instruction forms */
/* --------------------------------------------------------------------- */
/* The instruction includes the AL condition.
@@ -771,6 +771,12 @@ static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_
#endif /* SLJIT_CONFIG_ARM_V6 */
}
+static SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));
+}
+
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
static void reduce_code_size(struct sljit_compiler *compiler)
@@ -882,7 +888,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
/* Second code generation pass. */
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
@@ -945,6 +951,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!const_ || const_->addr >= word_count);
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+ *code_ptr = buf_ptr[-1];
+ }
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -1011,6 +1022,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} while (buf);
if (label && label->size == word_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -1111,17 +1125,23 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
const_ = compiler->consts;
while (const_) {
buf_ptr = (sljit_ins*)const_->addr;
- const_->addr = (sljit_uw)code_ptr;
- code_ptr[0] = (sljit_ins)buf_ptr;
- code_ptr[1] = *buf_ptr;
- if (*buf_ptr & (1 << 23))
- buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
- else
- buf_ptr += 1;
- /* Set the value again (can be a simple constant). */
- set_const_value((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
- code_ptr += 2;
+ /* Note: MVN = (MOV ^ 0x400000) */
+ SLJIT_ASSERT((*buf_ptr & 0xfdb00000) == MOV || (*buf_ptr & 0xfd100000) == LDR);
+
+ if ((*buf_ptr & 0x4000000) != 0) {
+ const_->addr = (sljit_uw)code_ptr;
+
+ code_ptr[0] = (sljit_ins)buf_ptr;
+ code_ptr[1] = *buf_ptr;
+ if (*buf_ptr & (1 << 23))
+ buf_ptr += ((*buf_ptr & 0xfff) >> 2) + 2;
+ else
+ buf_ptr += 1;
+ /* Set the value again (can be a simple constant). */
+ set_const_value((sljit_uw)code_ptr, executable_offset, *buf_ptr, 0);
+ code_ptr += 2;
+ }
const_ = const_->next;
}
@@ -1800,7 +1820,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
src2 = TMP_REG2;
} else
compiler->shift_imm = (sljit_uw)(-(sljit_sw)compiler->shift_imm) & 0x1f;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ROTR:
shift_type = 3;
@@ -2613,6 +2633,54 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst(compiler, ORR | RD(dst_reg) | RN(dst_reg) | RM8(TMP_REG2) | ((sljit_ins)(is_left ? 1 : 0) << 5) | 0x10 | RM(TMP_REG1));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r, tmp_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= 0x1f;
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));
+ src1 = TMP_REG1;
+ } else if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
+ src1 = TMP_REG1;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ tmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, tmp_r, src2, src2w, tmp_r));
+ src2 = tmp_r;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(src1) | RM(src2) | ((sljit_ins)shift_arg << 7)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_SIZE, dst_r, dst, dstw, TMP_REG1);
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -2624,9 +2692,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
case SLJIT_FAST_RETURN:
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
- else
+ if (FAST_IS_REG(src)) {
+ if (src != TMP_REG2)
+ FAIL_IF(push_inst(compiler, MOV | RD(TMP_REG2) | RM(src)));
+ } else
FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, src, srcw, TMP_REG1));
return push_inst(compiler, BX | RM(TMP_REG2));
@@ -2656,8 +2725,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
case SLJIT_FAST_ENTER:
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
- if (FAST_IS_REG(dst))
+ if (FAST_IS_REG(dst)) {
+ if (dst == TMP_REG2)
+ return SLJIT_SUCCESS;
return push_inst(compiler, MOV | RD(dst) | RM(TMP_REG2));
+ }
break;
case SLJIT_GET_RETURN_ADDRESS:
size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0);
@@ -3065,7 +3137,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
return 0x20000000;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_LESS:
return 0x30000000;
@@ -3073,7 +3145,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_NOT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
return 0x30000000;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_GREATER_EQUAL:
return 0x20000000;
@@ -3108,7 +3180,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_OVERFLOW:
if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
return 0x10000000;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_UNORDERED:
return 0x60000000;
@@ -3116,7 +3188,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_NOT_OVERFLOW:
if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
return 0x00000000;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ORDERED:
return 0x70000000;
@@ -3150,6 +3222,65 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, i;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
+ if (SLJIT_UNLIKELY(compiler->cpool_diff != CONST_POOL_EMPTY))
+ PTR_FAIL_IF(push_cpool(compiler));
+#endif /* SLJIT_CONFIG_ARM_V6 */
+
+ if (alignment <= SLJIT_LABEL_ALIGN_4) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);
+
+ for (i = (mask >> 2); i != 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ for (i = (buffers->size + 3) >> 2; i > 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
{
struct sljit_jump *jump;
@@ -3604,7 +3735,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2_reg)
{
- sljit_ins cc, tmp;
+ sljit_ins cc, tmp, tmp2;
CHECK_ERROR();
CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
@@ -3615,7 +3746,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
src1 = src2_reg;
src1w = 0;
src2_reg = dst_reg;
- type ^= 0x1;
+ if (!(type & SLJIT_COMPARE_SELECT))
+ type ^= 0x1;
}
if (src1 & SLJIT_MEM) {
@@ -3624,7 +3756,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
if (src2_reg != dst_reg) {
src1 = src2_reg;
src1w = 0;
- type ^= 0x1;
+ if (!(type & SLJIT_COMPARE_SELECT))
+ type ^= 0x1;
} else {
src1 = TMP_REG1;
src1w = 0;
@@ -3632,29 +3765,48 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
} else if (dst_reg != src2_reg)
FAIL_IF(push_inst(compiler, MOV | RD(dst_reg) | RM(src2_reg)));
- cc = get_cc(compiler, type & ~SLJIT_32);
+ if (type & SLJIT_COMPARE_SELECT)
+ type ^= 0x1;
+
+ cc = get_cc(compiler, type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT));
if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {
tmp = get_imm((sljit_uw)src1w);
- if (tmp)
+ if (tmp) {
+ if (type & SLJIT_COMPARE_SELECT)
+ FAIL_IF(push_inst(compiler, (CMP | SET_FLAGS | RN(dst_reg) | tmp)));
return push_inst(compiler, ((MOV | RD(dst_reg) | tmp) & ~COND_MASK) | cc);
+ }
tmp = get_imm(~(sljit_uw)src1w);
+ if (tmp && (type & SLJIT_COMPARE_SELECT)) {
+ tmp2 = get_imm((sljit_uw)-src1w);
+ if (tmp2)
+ FAIL_IF(push_inst(compiler, (CMN | SET_FLAGS | RN(dst_reg) | tmp2)));
+ else
+ tmp = 0;
+ }
+
if (tmp)
return push_inst(compiler, ((MVN | RD(dst_reg) | tmp) & ~COND_MASK) | cc);
#if (defined SLJIT_CONFIG_ARM_V7 && SLJIT_CONFIG_ARM_V7)
- tmp = (sljit_ins)src1w;
- FAIL_IF(push_inst(compiler, (MOVW & ~COND_MASK) | cc | RD(dst_reg) | ((tmp << 4) & 0xf0000) | (tmp & 0xfff)));
- if (tmp <= 0xffff)
- return SLJIT_SUCCESS;
- return push_inst(compiler, (MOVT & ~COND_MASK) | cc | RD(dst_reg) | ((tmp >> 12) & 0xf0000) | ((tmp >> 16) & 0xfff));
-#else /* !SLJIT_CONFIG_ARM_V7 */
+ if (!(type & SLJIT_COMPARE_SELECT)) {
+ tmp = (sljit_ins)src1w;
+ FAIL_IF(push_inst(compiler, (MOVW & ~COND_MASK) | cc | RD(dst_reg) | ((tmp << 4) & 0xf0000) | (tmp & 0xfff)));
+ if (tmp <= 0xffff)
+ return SLJIT_SUCCESS;
+ return push_inst(compiler, (MOVT & ~COND_MASK) | cc | RD(dst_reg) | ((tmp >> 12) & 0xf0000) | ((tmp >> 16) & 0xfff));
+ }
+#endif /* SLJIT_CONFIG_ARM_V7 */
+
FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));
src1 = TMP_REG1;
-#endif /* SLJIT_CONFIG_ARM_V7 */
}
+ if (type & SLJIT_COMPARE_SELECT)
+ FAIL_IF(push_inst(compiler, (CMP | SET_FLAGS | RN(dst_reg) | RM(src1))));
+
return push_inst(compiler, ((MOV | RD(dst_reg) | RM(src1)) & ~COND_MASK) | cc);
}
@@ -4688,13 +4840,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
return SLJIT_SUCCESS;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+#define SLJIT_EMIT_CONST_U8(c) \
+ (((c) & 0x100) != 0 ? (MVN | SRC2_IMM | (~(c) & 0xff)) : (MOV | SRC2_IMM | ((c) & 0xff)))
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
struct sljit_const *const_;
sljit_s32 dst_r;
+ sljit_s32 mem_flags = WORD_SIZE;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
@@ -4703,35 +4861,52 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ if (GET_OPCODE(op) == SLJIT_MOV_U8) {
+ PTR_FAIL_IF(push_inst(compiler, SLJIT_EMIT_CONST_U8(init_value) | RD(dst_r)));
+ mem_flags = BYTE_SIZE;
+ } else {
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
- PTR_FAIL_IF(push_inst_with_unique_literal(compiler,
- EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_ins)init_value));
- compiler->patches++;
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler,
+ EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), (sljit_ins)init_value));
+ compiler->patches++;
#else /* !SLJIT_CONFIG_ARM_V6 */
- PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));
+ PTR_FAIL_IF(emit_imm(compiler, dst_r, init_value));
#endif /* SLJIT_CONFIG_ARM_V6 */
+ }
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
+ PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, dst, dstw, TMP_REG1));
+
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_s32 dst_r;
+ sljit_s32 dst_r, target_r;
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = TMP_REG1;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | LOAD_DATA, TMP_REG2, dst, dstw, TMP_REG1));
+ }
+
#if (defined SLJIT_CONFIG_ARM_V6 && SLJIT_CONFIG_ARM_V6)
- PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, dst_r, TMP_PC, 0), 0));
+ PTR_FAIL_IF(push_inst_with_unique_literal(compiler, EMIT_DATA_TRANSFER(WORD_SIZE | LOAD_DATA, 1, target_r, TMP_PC, 0), 0));
compiler->patches++;
#else /* !SLJIT_CONFIG_ARM_V6 */
- PTR_FAIL_IF(push_inst(compiler, RD(dst_r)));
+ PTR_FAIL_IF(push_inst(compiler, RD(target_r)));
#endif /* SLJIT_CONFIG_ARM_V6 */
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
@@ -4742,6 +4917,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_com
compiler->size += 1;
#endif /* SLJIT_CONFIG_ARM_V7 */
+ if (op == SLJIT_ADD_ABS_ADDR)
+ PTR_FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(dst_r) | RM(TMP_REG1)));
+
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, dst, dstw, TMP_REG1));
return jump;
@@ -4752,7 +4930,21 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
set_jump_addr(addr, executable_offset, new_target, 1);
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
- set_const_value(addr, executable_offset, (sljit_uw)new_constant, 1);
+ sljit_ins *inst;
+
+ if (GET_OPCODE(op) != SLJIT_MOV_U8) {
+ set_const_value(addr, executable_offset, (sljit_uw)new_constant, 1);
+ return;
+ }
+
+ inst = (sljit_ins*)addr;
+ SLJIT_ASSERT((inst[0] & 0xfff00000) == (MOV | SRC2_IMM) || (inst[0] & 0xfff00000) == (MVN | SRC2_IMM));
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ *inst = SLJIT_EMIT_CONST_U8(new_constant) | (*inst & 0xf000);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
+ inst = (sljit_ins*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_64.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_64.c
index d80c9e546ee..dabbd3b0792 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_64.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_64.c
@@ -24,9 +24,15 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#ifdef __ARM_FEATURE_ATOMICS
+#define ARM_ATOMIC_INFO " (LSE)"
+#else
+#define ARM_ATOMIC_INFO ""
+#endif
+
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
{
- return "ARM-64" SLJIT_CPUINFO;
+ return "ARM-64" ARM_ATOMIC_INFO SLJIT_CPUINFO;
}
/* Length of an instruction word */
@@ -64,7 +70,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
#define VM(vm) ((sljit_ins)freg_map[vm] << 16)
/* --------------------------------------------------------------------- */
-/* Instrucion forms */
+/* Instruction forms */
/* --------------------------------------------------------------------- */
#define ADC 0x9a000000
@@ -91,6 +97,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
#define CLZ 0xdac01000
#define CSEL 0x9a800000
#define CSINC 0x9a800400
+#define CSINV 0xda800000
#define DMB_SY 0xd5033fbf
#define DUP_e 0x0e000400
#define DUP_g 0x0e000c00
@@ -385,6 +392,12 @@ static SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, slji
buf_ptr[3] = MOVK | ((sljit_ins)((sljit_uw)addr >> 48) << 5) | (3 << 21) | dst;
}
+static SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));
+}
+
static void reduce_code_size(struct sljit_compiler *compiler)
{
struct sljit_label *label;
@@ -499,7 +512,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reduce_code_size(compiler);
@@ -529,6 +542,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* These structures are ordered by their address. */
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+ *code_ptr = buf_ptr[-1];
+ }
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -565,6 +583,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} while (buf);
if (label && label->size == word_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -884,7 +905,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
if (flags & ARG1_IMM)
break;
imm = -imm;
- /* Fall through. */
+ SLJIT_FALLTHROUGH
case SLJIT_ADD:
if (op != SLJIT_SUB)
compiler->status_flags_state = SLJIT_CURRENT_FLAGS_ADD;
@@ -930,7 +951,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
FAIL_IF(push_inst(compiler, (ORN ^ inv_bits) | RD(dst) | RN(TMP_ZERO) | RM(reg)));
goto set_flags;
}
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_OR:
inst_bits = logical_imm(imm, LOGICAL_IMM_CHECK | ((flags & INT_OP) ? 16 : 32));
if (!inst_bits)
@@ -1039,7 +1060,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
if (dst == arg2)
return SLJIT_SUCCESS;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_MOV_U32:
SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1);
return push_inst(compiler, (MOV ^ W_OP) | RD(dst) | RM(arg2));
@@ -1124,7 +1145,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
case SLJIT_ROTL:
FAIL_IF(push_inst(compiler, (SUB ^ inv_bits) | RD(TMP_REG2) | RN(TMP_ZERO) | RM(arg2)));
arg2 = TMP_REG2;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ROTR:
return push_inst(compiler, (RORV ^ inv_bits) | RD(dst) | RN(arg1) | RM(arg2));
case SLJIT_MULADD:
@@ -1855,6 +1876,54 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst(compiler, (ORR ^ inv_bits) | RD(dst_reg) | RN(dst_reg) | RM(TMP_REG1));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r, tmp_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= 0x3f;
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG2, src1w));
+ src1 = TMP_REG2;
+ } else if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src1, src1w, TMP_REG2));
+ src1 = TMP_REG2;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ tmp_r = (src1 == TMP_REG2) ? TMP_REG1 : TMP_REG2;
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, tmp_r, src2, src2w, tmp_r));
+ src2 = tmp_r;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+ FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(src1) | RM(src2) | ((sljit_ins)shift_arg << 10)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2);
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -1864,9 +1933,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, MOV | RD(TMP_LR) | RM(src)));
- else
+ if (FAST_IS_REG(src)) {
+ if (src != TMP_LR)
+ FAIL_IF(push_inst(compiler, MOV | RD(TMP_LR) | RM(src)));
+ } else
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_LR, src, srcw, TMP_REG1));
return push_inst(compiler, RET | RN(TMP_LR));
@@ -1906,8 +1976,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_ENTER:
- if (FAST_IS_REG(dst))
+ if (FAST_IS_REG(dst)) {
+ if (dst == TMP_LR)
+ return SLJIT_SUCCESS;
return push_inst(compiler, MOV | RD(dst) | RM(TMP_LR));
+ }
break;
case SLJIT_GET_RETURN_ADDRESS:
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
@@ -2291,7 +2364,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
return 0x3;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_LESS:
return 0x2;
@@ -2299,7 +2372,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_NOT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
return 0x2;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_GREATER_EQUAL:
return 0x3;
@@ -2334,7 +2407,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_OVERFLOW:
if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
return 0x0;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_UNORDERED:
return 0x7;
@@ -2342,7 +2415,7 @@ static sljit_ins get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_NOT_OVERFLOW:
if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
return 0x1;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ORDERED:
return 0x6;
@@ -2376,6 +2449,60 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, i;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (alignment <= SLJIT_LABEL_ALIGN_4) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);
+
+ for (i = (mask >> 2); i != 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ for (i = (buffers->size + 3) >> 2; i > 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
{
struct sljit_jump *jump;
@@ -2565,6 +2692,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
sljit_s32 src2_reg)
{
sljit_ins inv_bits = (type & SLJIT_32) ? W_OP : 0;
+ sljit_ins op = CSEL;
+ sljit_ins cmp = 0;
sljit_ins cc;
CHECK_ERROR();
@@ -2575,15 +2704,38 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
if (src1 == SLJIT_IMM) {
if (type & SLJIT_32)
src1w = (sljit_s32)src1w;
- FAIL_IF(load_immediate(compiler, TMP_REG2, src1w));
- src1 = TMP_REG2;
+
+ if (src1w <= 1 && src1w >= -1) {
+ src1 = TMP_ZERO;
+ cmp = (SUBI ^ inv_bits) | (1 << 29) | RD(TMP_ZERO);
+
+ if (src1w == 1) {
+ op = CSINC;
+ cmp = (SUBI ^ inv_bits) | (1 << 29) | RD(TMP_ZERO) | (1 << 10);
+ } else if (src1w == -1) {
+ op = CSINV;
+ cmp = (ADDI ^ inv_bits) | (1 << 29) | RD(TMP_ZERO) | (1 << 10);
+ }
+
+ src1w = 0;
+ } else {
+ FAIL_IF(load_immediate(compiler, TMP_REG2, src1w));
+ src1 = TMP_REG2;
+ }
} else if (src1 & SLJIT_MEM) {
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src1, src1w, TMP_REG2));
src1 = TMP_REG2;
}
- cc = get_cc(compiler, type & ~SLJIT_32);
- return push_inst(compiler, (CSEL ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(src2_reg) | RM(src1));
+ if (type & SLJIT_COMPARE_SELECT) {
+ type ^= 0x1;
+ if (cmp == 0)
+ cmp = (SUB ^ inv_bits) | (1 << 29) | RD(TMP_ZERO) | RM(src1);
+ FAIL_IF(push_inst(compiler, cmp | RN(src2_reg)));
+ }
+
+ cc = get_cc(compiler, type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT));
+ return push_inst(compiler, (op ^ inv_bits) | (cc << 12) | RD(dst_reg) | RN(src2_reg) | RM(src1));
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *compiler, sljit_s32 type,
@@ -2701,19 +2853,19 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_mem_update(struct sljit_compiler *
break;
case SLJIT_MOV_S8:
sign = 1;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_MOV_U8:
inst = STURBI | (MEM_SIZE_SHIFT(BYTE_SIZE) << 30) | 0x400;
break;
case SLJIT_MOV_S16:
sign = 1;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_MOV_U16:
inst = STURBI | (MEM_SIZE_SHIFT(HALF_SIZE) << 30) | 0x400;
break;
case SLJIT_MOV_S32:
sign = 1;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_MOV_U32:
case SLJIT_MOV32:
inst = STURBI | (MEM_SIZE_SHIFT(INT_SIZE) << 30) | 0x400;
@@ -3378,6 +3530,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
{
sljit_ins ins;
sljit_ins cmp = 0;
+ SLJIT_UNUSED_ARG(temp_reg); /* !__ARM_FEATURE_ATOMICS */
CHECK_ERROR();
CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));
@@ -3467,6 +3620,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
CHECK_ERROR();
CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
dst_reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
@@ -3500,13 +3654,21 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
return SLJIT_SUCCESS;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+#define SLJIT_EMIT_CONST_U8(c) \
+ (((c) & 0x100) != 0 ? (MOVN | (sljit_ins)((~(c) & 0xff) << 5)) : (MOVZ | (sljit_ins)(((c) & 0xff) << 5)))
+#define SLJIT_EMIT_CONST_S32(c) \
+ (((c) < 0) ? (MOVN | (sljit_ins)((~(c) & 0xffff) << 5)) : (MOVZ | (sljit_ins)(((c) & 0xffff) << 5)))
+
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
struct sljit_const *const_;
sljit_s32 dst_r;
+ sljit_s32 mem_flags = WORD_SIZE | STORE;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
@@ -3514,24 +3676,58 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
set_const(const_, compiler);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, (sljit_uw)init_value));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ PTR_FAIL_IF(push_inst(compiler, SLJIT_EMIT_CONST_U8(init_value) | RD(dst_r)));
+ mem_flags = BYTE_SIZE | STORE;
+ break;
+
+ case SLJIT_MOV32:
+ case SLJIT_MOV_S32:
+ if (GET_OPCODE(op) == SLJIT_MOV32) {
+ init_value = (sljit_u32)init_value;
+ mem_flags = INT_SIZE | STORE;
+ } else
+ init_value = (sljit_s32)init_value;
+
+ PTR_FAIL_IF(push_inst(compiler, SLJIT_EMIT_CONST_S32(init_value) | RD(dst_r)));
+ PTR_FAIL_IF(push_inst(compiler, MOVK | (1 << 21) | (sljit_ins)((init_value >> 11) & 0x1fffe0) | RD(dst_r)));
+ break;
+
+ default:
+ PTR_FAIL_IF(emit_imm64_const(compiler, dst_r, (sljit_uw)init_value));
+ break;
+ }
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
+ PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, dst, dstw, TMP_REG2));
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_s32 dst_r;
+ sljit_s32 dst_r, target_r;
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(push_inst(compiler, RD(dst_r)));
+
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = TMP_REG2;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, dst, dstw, TMP_REG2));
+ }
+
+ PTR_FAIL_IF(push_inst(compiler, RD(target_r)));
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF(!jump);
@@ -3539,6 +3735,9 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_com
compiler->size += 3;
+ if (op == SLJIT_ADD_ABS_ADDR)
+ PTR_FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RN(dst_r) | RM(TMP_REG2)));
+
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
@@ -3565,7 +3764,42 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_CACHE_FLUSH(inst, inst + 4);
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ sljit_ins* inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ inst = (sljit_ins*)addr;
+ SLJIT_ASSERT((inst[0] & 0xffe00000) == MOVZ || (inst[0] & 0xffe00000) == MOVN);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ inst[0] = SLJIT_EMIT_CONST_U8(new_constant) | (inst[0] & 0x1f);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ return;
+
+ case SLJIT_MOV32:
+ case SLJIT_MOV_S32:
+ if (GET_OPCODE(op) == SLJIT_MOV32)
+ new_constant = (sljit_u32)new_constant;
+ else
+ new_constant = (sljit_s32)new_constant;
+
+ inst = (sljit_ins*)addr;
+ SLJIT_ASSERT(((inst[0] & 0xffe00000) == MOVZ || (inst[0] & 0xffe00000) == MOVN) && (inst[1] & 0xffe00000) == (MOVK | (1 << 21)));
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ inst[0] = SLJIT_EMIT_CONST_S32(new_constant) | (inst[0] & 0x1f);
+ inst[1] = MOVK | (1 << 21) | (sljit_ins)((new_constant >> 11) & 0x1fffe0) | (inst[1] & 0x1f);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ return;
+
+ default:
+ sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ return;
+ }
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_T2_32.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_T2_32.c
index d8058ab6ea4..eab9ec1ff05 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_T2_32.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeARM_T2_32.c
@@ -102,7 +102,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1)
(COPY_BITS(imm, 11, 26, 1) | COPY_BITS(imm, 8, 12, 3) | ((sljit_ins)imm & 0xff))
/* --------------------------------------------------------------------- */
-/* Instrucion forms */
+/* Instruction forms */
/* --------------------------------------------------------------------- */
/* dot '.' changed to _
@@ -160,6 +160,7 @@ static const sljit_u8 freg_ebit_map[((SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) << 1)
#define LSR_WI 0xea4f0010
#define MLA 0xfb000000
#define MOV 0x4600
+#define MOVI 0x2000
#define MOVS 0x0000
#define MOVSI 0x2000
#define MOVT 0xf2c00000
@@ -444,6 +445,9 @@ static SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, slji
diff = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);
+ if ((jump->flags & (JUMP_MOV_ADDR | IS_ABS)) == (JUMP_MOV_ADDR | IS_ABS))
+ diff &= ~(sljit_sw)1;
+
if (SLJIT_UNLIKELY(type == 0)) {
ins = (jump->flags & JUMP_MOV_ADDR) ? *jump_inst : RDN3(TMP_REG1);
set_imm32_const((sljit_u16*)jump->addr, ins, (sljit_uw)diff);
@@ -506,6 +510,12 @@ static SLJIT_INLINE void generate_jump_or_mov_addr(struct sljit_jump *jump, slji
jump_inst[1] |= 0xd000;
}
+static SLJIT_INLINE sljit_u16 *process_extended_label(sljit_u16 *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_u16*)((sljit_uw)code_ptr & ~(ext_label->data));
+}
+
static void reduce_code_size(struct sljit_compiler *compiler)
{
struct sljit_label *label;
@@ -615,7 +625,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reduce_code_size(compiler);
@@ -645,6 +655,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* These structures are ordered by their address. */
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+ *code_ptr = buf_ptr[-1];
+ }
+
label->u.addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -682,6 +697,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} while (buf);
if (label && label->size == half_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = ((sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset)) | 0x1;
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -1025,7 +1043,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
return push_inst32(compiler, ASR_WI | (flags & SET_FLAGS) | RD4(dst) | RM4(reg) | IMM5(imm));
case SLJIT_ROTL:
imm = (imm ^ 0x1f) + 1;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
default: /* SLJIT_ROTR */
return push_inst32(compiler, ROR_WI | RD4(dst) | RM4(reg) | IMM5(imm));
}
@@ -1161,7 +1179,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
FAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));
arg2 = (sljit_uw)reg;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_SHL:
if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
return push_inst16(compiler, LSLS | RD3(dst) | RN3(arg2));
@@ -1170,7 +1188,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
FAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));
arg2 = (sljit_uw)reg;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_LSHR:
if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
return push_inst16(compiler, LSRS | RD3(dst) | RN3(arg2));
@@ -1179,7 +1197,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
FAIL_IF(push_inst32(compiler, ANDI | RD4(reg) | RN4(arg2) | 0x1f));
arg2 = (sljit_uw)reg;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ASHR:
if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
return push_inst16(compiler, ASRS | RD3(dst) | RN3(arg2));
@@ -1188,7 +1206,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s
reg = (arg2 == TMP_REG1) ? TMP_REG1 : TMP_REG2;
FAIL_IF(push_inst32(compiler, RSB_WI | RD4(reg) | RN4(arg2) | 0));
arg2 = (sljit_uw)reg;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ROTR:
if (dst == (sljit_s32)arg1 && IS_2_LO_REGS(dst, arg2))
return push_inst16(compiler, RORS | RD3(dst) | RN3(arg2));
@@ -2182,6 +2200,54 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst32(compiler, ORR_W | RD4(dst_reg) | RN4(dst_reg) | RM4(TMP_REG1));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r, tmp_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= 0x1f;
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));
+ src1 = TMP_REG1;
+ } else if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG1, src1, src1w, TMP_REG1));
+ src1 = TMP_REG1;
+ }
+
+ if (src2 & SLJIT_MEM) {
+ tmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+ FAIL_IF(emit_op_mem(compiler, WORD_SIZE, tmp_r, src2, src2w, tmp_r));
+ src2 = tmp_r;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ FAIL_IF(push_inst32(compiler, ADD_W | RD4(dst_r) | RN4(src1) | RM4(src2) | ((sljit_ins)(shift_arg & 0x3) << 6) | ((sljit_ins)(shift_arg & 0x1c) << 10)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG1);
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -2193,9 +2259,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
case SLJIT_FAST_RETURN:
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
- else
+ if (FAST_IS_REG(src)) {
+ if (src != TMP_REG2)
+ FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(TMP_REG2, src)));
+ } else
FAIL_IF(emit_op_mem(compiler, WORD_SIZE, TMP_REG2, src, srcw, TMP_REG2));
return push_inst16(compiler, BX | RN3(TMP_REG2));
@@ -2224,8 +2291,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
case SLJIT_FAST_ENTER:
SLJIT_ASSERT(reg_map[TMP_REG2] == 14);
- if (FAST_IS_REG(dst))
+ if (FAST_IS_REG(dst)) {
+ if (dst == TMP_REG2)
+ return SLJIT_SUCCESS;
return push_inst16(compiler, MOV | SET_REGS44(dst, TMP_REG2));
+ }
break;
case SLJIT_GET_RETURN_ADDRESS:
size = GET_SAVED_REGISTERS_SIZE(compiler->scratches, compiler->saveds - SLJIT_KEPT_SAVEDS_COUNT(compiler->options), 0);
@@ -2632,7 +2702,7 @@ static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
return 0x2;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_LESS:
return 0x3;
@@ -2640,7 +2710,7 @@ static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_NOT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_ADD)
return 0x3;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_GREATER_EQUAL:
return 0x2;
@@ -2675,7 +2745,7 @@ static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_OVERFLOW:
if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
return 0x1;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_UNORDERED:
return 0x6;
@@ -2683,7 +2753,7 @@ static sljit_uw get_cc(struct sljit_compiler *compiler, sljit_s32 type)
case SLJIT_NOT_OVERFLOW:
if (!(compiler->status_flags_state & (SLJIT_CURRENT_FLAGS_ADD | SLJIT_CURRENT_FLAGS_SUB)))
return 0x0;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ORDERED:
return 0x7;
@@ -2717,6 +2787,60 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, i;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (alignment <= SLJIT_LABEL_ALIGN_2) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_u16);
+
+ for (i = (mask >> 1); i != 0; i--)
+ PTR_FAIL_IF(push_inst16(compiler, NOP));
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ for (i = (buffers->size + 1) >> 1; i > 0; i--)
+ PTR_FAIL_IF(push_inst16(compiler, NOP));
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
{
struct sljit_jump *jump;
@@ -3166,7 +3290,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2_reg)
{
- sljit_uw cc, tmp;
+ sljit_uw cc, tmp, tmp2;
CHECK_ERROR();
CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
@@ -3177,7 +3301,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
src1 = src2_reg;
src1w = 0;
src2_reg = dst_reg;
- type ^= 0x1;
+ if (!(type & SLJIT_COMPARE_SELECT))
+ type ^= 0x1;
}
if (src1 & SLJIT_MEM) {
@@ -3186,7 +3311,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
if (src2_reg != dst_reg) {
src1 = src2_reg;
src1w = 0;
- type ^= 0x1;
+ if (!(type & SLJIT_COMPARE_SELECT))
+ type ^= 0x1;
} else {
src1 = TMP_REG1;
src1w = 0;
@@ -3194,9 +3320,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
} else if (dst_reg != src2_reg)
FAIL_IF(push_inst16(compiler, MOV | SET_REGS44(dst_reg, src2_reg)));
- cc = get_cc(compiler, type & ~SLJIT_32);
+ if ((type & SLJIT_COMPARE_SELECT))
+ type ^= 0x1;
+ cc = get_cc(compiler, type & ~(SLJIT_32 | SLJIT_COMPARE_SELECT));
+
+ if (src1 == SLJIT_IMM && (type & SLJIT_COMPARE_SELECT)) {
+ tmp = (sljit_uw)src1w;
+ if (tmp <= 0xff && reg_map[dst_reg] <= 7) {
+ if (type & SLJIT_COMPARE_SELECT)
+ FAIL_IF(push_inst16(compiler, CMPI | IMM8(tmp) | RDN3(dst_reg)));
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ return push_inst16(compiler, MOVI | IMM8(tmp) | RDN3(dst_reg));
+ }
+
+ tmp = get_imm((sljit_uw)src1w);
+ if (tmp != INVALID_IMM) {
+ if (type & SLJIT_COMPARE_SELECT)
+ FAIL_IF(push_inst32(compiler, CMPI_W | RN4(dst_reg) | tmp));
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ return push_inst32(compiler, MOV_WI | RD4(dst_reg) | tmp);
+ }
+
+ tmp = get_imm(~(sljit_uw)src1w);
+ if (tmp != INVALID_IMM && (type & SLJIT_COMPARE_SELECT)) {
+ tmp2 = get_imm(NEGATE(src1w));
+ if (tmp2 != INVALID_IMM)
+ FAIL_IF(push_inst32(compiler, CMNI_W | RN4(dst_reg) | tmp2));
+ else
+ tmp = INVALID_IMM;
+ }
+
+ if (tmp != INVALID_IMM) {
+ FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
+ return push_inst32(compiler, MVN_WI | RD4(dst_reg) | tmp);
+ }
+
+ if (type & SLJIT_COMPARE_SELECT) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, (sljit_uw)src1w));
+ src1 = TMP_REG1;
+ }
+ }
if (src1 != SLJIT_IMM) {
+ if (type & SLJIT_COMPARE_SELECT) {
+ if (IS_2_LO_REGS(dst_reg, src1))
+ FAIL_IF(push_inst16(compiler, CMP | RD3(dst_reg) | RN3(src1)));
+ else
+ FAIL_IF(push_inst16(compiler, CMP_X | SET_REGS44(dst_reg, src1)));
+ }
+
FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
return push_inst16(compiler, MOV | SET_REGS44(dst_reg, src1));
}
@@ -3210,18 +3382,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
| COPY_BITS(tmp, 12, 16, 4) | COPY_BITS(tmp, 11, 26, 1) | COPY_BITS(tmp, 8, 12, 3) | (tmp & 0xff));
}
- tmp = get_imm((sljit_uw)src1w);
- if (tmp != INVALID_IMM) {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- return push_inst32(compiler, MOV_WI | RD4(dst_reg) | tmp);
- }
-
- tmp = get_imm(~(sljit_uw)src1w);
- if (tmp != INVALID_IMM) {
- FAIL_IF(push_inst16(compiler, IT | (cc << 4) | 0x8));
- return push_inst32(compiler, MVN_WI | RD4(dst_reg) | tmp);
- }
-
FAIL_IF(push_inst16(compiler, IT | (cc << 4) | ((cc & 0x1) << 3) | 0x4));
tmp = (sljit_uw)src1w;
@@ -4357,13 +4517,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
return SLJIT_SUCCESS;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
struct sljit_const *const_;
sljit_s32 dst_r;
+ sljit_s32 mem_flags = WORD_SIZE | STORE;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
@@ -4371,32 +4534,55 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
set_const(const_, compiler);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, (sljit_uw)init_value));
+
+ if (GET_OPCODE(op) == SLJIT_MOV_U8) {
+ PTR_FAIL_IF(push_inst32(compiler,
+ ((init_value & 0x100) != 0 ? (MVN_WI | (~init_value & 0xff)) : (MOV_WI | (init_value & 0xff))) | RD4(dst_r)));
+ mem_flags = BYTE_SIZE | STORE;
+ } else
+ PTR_FAIL_IF(emit_imm32_const(compiler, dst_r, (sljit_uw)init_value));
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
+ PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, dst, dstw, TMP_REG2));
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_s32 dst_r;
+ sljit_s32 dst_r, target_r;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = TMP_REG1;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE, dst_r, dst, dstw, TMP_REG1));
+ }
+
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF(!jump);
set_mov_addr(jump, compiler, 0);
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
- PTR_FAIL_IF(push_inst16(compiler, RDN3(dst_r)));
+ if (op != SLJIT_MOV_ADDR)
+ jump->flags |= IS_ABS;
+
+ PTR_FAIL_IF(push_inst16(compiler, RDN3(target_r)));
compiler->size += 3;
+ if (op == SLJIT_ADD_ABS_ADDR)
+ PTR_FAIL_IF(push_inst16(compiler, ADD | SET_REGS44(dst_r, TMP_REG1)));
+
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG2));
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_SIZE | STORE, dst_r, dst, dstw, TMP_REG1));
return jump;
}
@@ -4412,7 +4598,28 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_CACHE_FLUSH(inst, inst + 4);
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ sljit_u16 *inst;
+
+ if (GET_OPCODE(op) != SLJIT_MOV_U8) {
+ sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ return;
+ }
+
+ inst = (sljit_u16*)addr;
+ SLJIT_ASSERT(inst[0] == (MOV_WI >> 16) || inst[0] == (MVN_WI >> 16));
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+
+ if ((new_constant & 0x100) != 0) {
+ inst[0] = (sljit_u16)(MVN_WI >> 16);
+ new_constant = ~new_constant;
+ } else
+ inst[0] = (sljit_u16)(MOV_WI >> 16);
+
+ inst[1] = (sljit_u16)((new_constant & 0xff) | (inst[1] & 0xf00));
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
+ inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst + 1, inst + 2);
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeLOONGARCH_64.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeLOONGARCH_64.c
index 73868ca186a..13319669a55 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeLOONGARCH_64.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeLOONGARCH_64.c
@@ -53,7 +53,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
};
/* --------------------------------------------------------------------- */
-/* Instrucion forms */
+/* Instruction forms */
/* --------------------------------------------------------------------- */
/*
@@ -256,6 +256,7 @@ lower parts in the instruction word, denoted by the “L” and “H” suffixes
/* Other instructions */
#define BREAK OPC_3R(0x54)
#define DBGCALL OPC_3R(0x55)
+#define NOP ANDI
#define SYSCALL OPC_3R(0x56)
/* Basic Floating-Point Instructions */
@@ -580,6 +581,12 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec
ins[1] = ORI | RD(reg) | RJ(reg) | IMM_I12(addr);
}
+static SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));
+}
+
static void reduce_code_size(struct sljit_compiler *compiler)
{
struct sljit_label *label;
@@ -694,7 +701,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reduce_code_size(compiler);
@@ -724,6 +731,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* These structures are ordered by their address. */
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+ *code_ptr = buf_ptr[-1];
+ }
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -759,6 +771,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} while (buf);
if (label && label->size == word_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)code_ptr;
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -893,14 +908,18 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
if (imm <= 0x7fffffffl && imm >= -0x80000000l) {
FAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)(((imm & 0xffffffff) >> 12) << 5)));
- return push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm));
+ if (IMM_I12(imm) != 0)
+ return push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm));
+ return SLJIT_SUCCESS;
} else if (imm <= 0x7ffffffffffffl && imm >= -0x8000000000000l) {
FAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)(((imm & 0xffffffff) >> 12) << 5)));
- FAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm)));
+ if (IMM_I12(imm) != 0)
+ FAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm)));
return push_inst(compiler, LU32I_D | RD(dst_r) | (sljit_ins)(((imm >> 32) & 0xfffff) << 5));
}
FAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)(((imm & 0xffffffff) >> 12) << 5)));
- FAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm)));
+ if (IMM_I12(imm) != 0)
+ FAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(imm)));
FAIL_IF(push_inst(compiler, LU32I_D | RD(dst_r) | (sljit_ins)(((imm >> 32) & 0xfffff) << 5)));
return push_inst(compiler, LU52I_D | RD(dst_r) | RJ(dst_r) | IMM_I12(imm >> 52));
}
@@ -1596,7 +1615,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (src2 >= 0)
FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(0)));
else {
- FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(src1) | IMM_I12(-1)));
+ FAIL_IF(push_inst(compiler, INST(ADDI, op) | RD(EQUAL_FLAG) | RJ(TMP_ZERO) | IMM_I12(-1)));
FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RJ(src1) | RK(EQUAL_FLAG)));
}
} else if (op & SLJIT_SET_Z)
@@ -1897,7 +1916,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
case SLJIT_BREAKPOINT:
return push_inst(compiler, BREAK);
case SLJIT_NOP:
- return push_inst(compiler, ANDI | RD(TMP_ZERO) | RJ(TMP_ZERO) | IMM_I12(0));
+ return push_inst(compiler, NOP);
case SLJIT_LMUL_UW:
FAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(SLJIT_R1) | IMM_I12(0)));
FAIL_IF(push_inst(compiler, MULH_DU | RD(SLJIT_R1) | RJ(SLJIT_R0) | RK(SLJIT_R1)));
@@ -2155,6 +2174,55 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst(compiler, OR | RD(dst_reg) | RJ(dst_reg) | RK(TMP_REG1));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r, tmp_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
+ src2 = TMP_REG2;
+ }
+
+ if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+ src1 = TMP_REG1;
+ } else if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1 = TMP_REG1;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ tmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+ FAIL_IF(push_inst(compiler, SLLI_D | RD(tmp_r) | RJ(src2) | IMM_I12(shift_arg)));
+ FAIL_IF(push_inst(compiler, ADD_D | RD(dst_r) | RJ(src1) | RK(tmp_r)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, WORD_DATA, dst_r, dst, dstw, 0, 0);
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -2166,9 +2234,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ADDI_D | RD(RETURN_ADDR_REG) | RJ(src) | IMM_I12(0)));
- else
+ if (FAST_IS_REG(src)) {
+ if (src != RETURN_ADDR_REG)
+ FAIL_IF(push_inst(compiler, ADDI_D | RD(RETURN_ADDR_REG) | RJ(src) | IMM_I12(0)));
+ } else
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
return push_inst(compiler, JIRL | RD(TMP_ZERO) | RJ(RETURN_ADDR_REG) | IMM_I12(0));
@@ -2207,8 +2276,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_ENTER:
- if (FAST_IS_REG(dst))
+ if (FAST_IS_REG(dst)) {
+ if (dst == RETURN_ADDR_REG)
+ return SLJIT_SUCCESS;
return push_inst(compiler, ADDI_D | RD(dst) | RJ(RETURN_ADDR_REG) | IMM_I12(0));
+ }
SLJIT_ASSERT(RETURN_ADDR_REG == TMP_REG2);
break;
@@ -2676,6 +2748,60 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, i;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (alignment <= SLJIT_LABEL_ALIGN_4) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);
+
+ for (i = (mask >> 2); i != 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ for (i = (buffers->size + 3) >> 2; i > 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
static sljit_ins get_jump_instruction(sljit_s32 type)
{
switch (type) {
@@ -3032,19 +3158,27 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
{
sljit_ins *ptr;
sljit_uw size;
+ sljit_s32 is_compare = (type & SLJIT_COMPARE_SELECT);
sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
CHECK_ERROR();
CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
ADJUST_LOCAL_OFFSET(src1, src1w);
+ if (src1 == SLJIT_IMM && type & SLJIT_32)
+ src1w = (sljit_s32)src1w;
+
+ type &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);
+
if (dst_reg != src2_reg) {
if (dst_reg == src1) {
src1 = src2_reg;
src1w = 0;
- type ^= 0x1;
+ if (!is_compare)
+ type ^= 0x1;
} else {
if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
+ SLJIT_ASSERT(!(type & SLJIT_COMPARE_SELECT));
FAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG1) | RJ(dst_reg) | IMM_I12(0)));
if ((src1 & REG_MASK) == dst_reg)
@@ -3058,6 +3192,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
}
}
+ if (is_compare) {
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG3, src1, src1w));
+ } else if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG3, src1w));
+ } else
+ FAIL_IF(push_inst(compiler, ADDI_D | RD(TMP_REG3) | RJ(src1) | IMM_I12(0)));
+ }
+
size = compiler->size;
ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
@@ -3067,13 +3210,35 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
if (src1 & SLJIT_MEM) {
FAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w));
} else if (src1 == SLJIT_IMM) {
- if (type & SLJIT_32)
- src1w = (sljit_s32)src1w;
FAIL_IF(load_immediate(compiler, dst_reg, src1w));
} else
FAIL_IF(push_inst(compiler, ADDI_D | RD(dst_reg) | RJ(src1) | IMM_I12(0)));
- *ptr = get_jump_instruction(type & ~SLJIT_32) | IMM_I16(compiler->size - size);
+ if (is_compare) {
+ switch (type) {
+ case SLJIT_LESS:
+ case SLJIT_LESS_EQUAL:
+ *ptr = BGEU;
+ break;
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_EQUAL:
+ *ptr = BLTU;
+ break;
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ *ptr = BGE;
+ break;
+ default:
+ *ptr = BLT;
+ break;
+ }
+
+ *ptr |= RJ(TMP_REG3) | RD(dst_reg);
+ } else {
+ *ptr = get_jump_instruction(type);
+ }
+
+ *ptr |= IMM_I16(compiler->size - size);
return SLJIT_SUCCESS;
}
@@ -3830,13 +3995,16 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_CACHE_FLUSH(inst, inst + 4);
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
struct sljit_const *const_;
sljit_s32 dst_r;
+ sljit_s32 mem_flags = WORD_DATA;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
@@ -3844,39 +4012,112 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
set_const(const_, compiler);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(emit_const(compiler, dst_r, init_value, 0));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ if (init_value & 0x100)
+ init_value |= 0xf00;
+ else
+ init_value &= 0xff;
+
+ PTR_FAIL_IF(push_inst(compiler, ADDI_D | RD(dst_r) | RJ(TMP_ZERO) | IMM_I12(init_value)));
+ mem_flags = BYTE_DATA;
+ break;
+
+ case SLJIT_MOV32:
+ mem_flags = INT_DATA;
+ SLJIT_FALLTHROUGH
+ case SLJIT_MOV_S32:
+ PTR_FAIL_IF(push_inst(compiler, LU12I_W | RD(dst_r) | (sljit_ins)((init_value >> 7) & 0x1ffffe0)));
+ PTR_FAIL_IF(push_inst(compiler, ORI | RD(dst_r) | RJ(dst_r) | IMM_I12(init_value)));
+ break;
+
+ default:
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value, 0));
+ break;
+ }
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
+ PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, dst, dstw));
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_s32 dst_r;
+ sljit_s32 dst_r, target_r;
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = TMP_REG1;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, dst, dstw));
+ }
+
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF(!jump);
set_mov_addr(jump, compiler, 0);
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
+ PTR_FAIL_IF(push_inst(compiler, (sljit_ins)target_r));
compiler->size += JUMP_MAX_SIZE - 1;
+ if (op == SLJIT_ADD_ABS_ADDR)
+ PTR_FAIL_IF(push_inst(compiler, ADD_D | RD(dst_r) | RJ(dst_r) | RK(TMP_REG1)));
+
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
return jump;
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ sljit_ins* inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ inst = (sljit_ins*)addr;
+ SLJIT_ASSERT((inst[0] & OPC_2RI12(0xb)) == ADDI_D);
+
+ if (new_constant & 0x100)
+ new_constant |= 0xf00;
+ else
+ new_constant &= 0xff;
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ inst[0] = (inst[0] & 0xffc003ff) | (sljit_ins)((new_constant & 0xfff) << 10);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ return;
+
+ case SLJIT_MOV32:
+ case SLJIT_MOV_S32:
+ inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & OPC_1RI20(0xa)) == LU12I_W && (inst[1] & OPC_2RI12(0xe)) == ORI);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ inst[0] = (inst[0] & (OPC_1RI20(0xa) | 0x1f)) | (sljit_ins)((new_constant >> 7) & 0x1ffffe0);
+ inst[1] = (inst[1] & (OPC_2RI12(0xe) | 0x3ff)) | (sljit_ins)((new_constant & 0xfff) << 10);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ return;
+
+ default:
+ sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ return;
+ }
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_32.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_32.c
index 91153e5f258..83979617d37 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_32.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_32.c
@@ -196,18 +196,13 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ inst[0] = (inst[0] & 0xffff0000) | IMM(new_target >> 16);
+ inst[1] = (inst[1] & 0xffff0000) | IMM(new_target);
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
-
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr, sljit_u32 *extra_space)
{
sljit_u32 is_tail_call = *extra_space & SLJIT_CALL_RETURN;
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_64.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_64.c
index b9f03a7bd24..965931b8c9a 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_64.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_64.c
@@ -202,20 +202,15 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_UNUSED_ARG(executable_offset);
SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);
- inst[0] = (inst[0] & 0xffff0000) | ((sljit_ins)(new_target >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | ((sljit_ins)(new_target >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000) | ((sljit_ins)(new_target >> 16) & 0xffff);
- inst[5] = (inst[5] & 0xffff0000) | ((sljit_ins)new_target & 0xffff);
+ inst[0] = (inst[0] & 0xffff0000) | IMM(new_target >> 48);
+ inst[1] = (inst[1] & 0xffff0000) | IMM(new_target >> 32);
+ inst[3] = (inst[3] & 0xffff0000) | IMM(new_target >> 16);
+ inst[5] = (inst[5] & 0xffff0000) | IMM(new_target);
SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 6);
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
-{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
-}
-
static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_types, sljit_ins *ins_ptr)
{
sljit_s32 arg_count = 0;
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_common.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_common.c
index 1b951fe1834..771abfec247 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_common.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeMIPS_common.c
@@ -121,7 +121,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = {
#endif /* SLJIT_CONFIG_MIPS_32 */
/* --------------------------------------------------------------------- */
-/* Instrucion forms */
+/* Instruction forms */
/* --------------------------------------------------------------------- */
#define S(s) ((sljit_ins)reg_map[s] << 21)
@@ -709,6 +709,12 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump)
ins[1] = ORI | S(reg) | T(reg) | IMM(addr & 0xffff);
}
+static SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));
+}
+
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
{
struct sljit_memory_fragment *buf;
@@ -725,7 +731,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reverse_buf(compiler);
code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
@@ -752,6 +758,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* These structures are ordered by their address. */
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+ *code_ptr = buf_ptr[-1];
+ }
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -796,6 +807,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} while (buf);
if (label && label->size == word_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)code_ptr;
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -1532,11 +1546,11 @@ static sljit_s32 emit_op_mem(struct sljit_compiler *compiler, sljit_s32 flags, s
return push_inst(compiler, data_transfer_insts[flags & MEM_MASK] | SA(tmp_ar) | TA(reg_ar) | IMM(argw), delay_slot);
}
-static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
+static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg_ar, sljit_s32 arg1, sljit_sw arg1w, sljit_s32 arg2, sljit_sw arg2w)
{
- if (getput_arg_fast(compiler, flags, reg, arg1, arg1w))
+ if (getput_arg_fast(compiler, flags, reg_ar, arg1, arg1w))
return compiler->error;
- return getput_arg(compiler, flags, reg, arg1, arg1w, arg2, arg2w);
+ return getput_arg(compiler, flags, reg_ar, arg1, arg1w, arg2, arg2w);
}
#define EMIT_LOGICAL(op_imm, op_reg) \
@@ -2167,7 +2181,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
FAIL_IF(push_inst(compiler, SELECT_OP(DSUBU, SUBU) | SA(0) | T(src2) | D(TMP_REG2), DR(TMP_REG2)));
src2 = TMP_REG2;
}
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ROTR:
EMIT_SHIFT(DROTR, DROTR32, ROTR, DROTRV, ROTRV);
@@ -2634,7 +2648,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
if ((src1 == SLJIT_IMM && src1w == -1) || (src2 == SLJIT_IMM && src2w == -1)) {
return emit_op(compiler, op, flags | CUMULATIVE_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
}
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_AND:
case SLJIT_OR:
return emit_op(compiler, op, flags | CUMULATIVE_OP | LOGICAL_OP | IMM_OP, dst, dstw, src1, src1w, src2, src2w);
@@ -2780,6 +2794,59 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst(compiler, OR | S(dst_reg) | T(TMP_REG1) | D(dst_reg), DR(dst_reg));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r, tmp_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), src2, src2w, src1, src1w));
+ src2 = TMP_REG2;
+ }
+
+ if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
+ src1 = TMP_REG1;
+ } else if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG1), src1, src1w, dst, dstw));
+ src1 = TMP_REG1;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ tmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ FAIL_IF(push_inst(compiler, (shift_arg >= 32 ? DSLL32 : DSLL) | T(src2) | D(tmp_r) | SH_IMM(shift_arg & 0x1f), DR(tmp_r)));
+#else /* !SLJIT_CONFIG_MIPS_64 */
+ FAIL_IF(push_inst(compiler, SLL | T(src2) | D(tmp_r) | SH_IMM(shift_arg), DR(tmp_r)));
+#endif /* SLJIT_CONFIG_MIPS_64 */
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src1) | T(tmp_r) | D(dst_r), DR(dst_r)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, WORD_DATA, DR(dst_r), dst, dstw, 0, 0);
+ return SLJIT_SUCCESS;
+}
+
#undef SELECT_OP3
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
@@ -2791,9 +2858,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
- else
+ if (FAST_IS_REG(src)) {
+ if (DR(src) != RETURN_ADDR_REG)
+ FAIL_IF(push_inst(compiler, ADDU_W | S(src) | TA(0) | DA(RETURN_ADDR_REG), RETURN_ADDR_REG));
+ } else
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
FAIL_IF(push_inst(compiler, JR | SA(RETURN_ADDR_REG), UNMOVABLE_INS));
@@ -2825,8 +2893,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_ENTER:
- if (FAST_IS_REG(dst))
+ if (FAST_IS_REG(dst)) {
+ if (DR(dst) == RETURN_ADDR_REG)
+ return SLJIT_SUCCESS;
return push_inst(compiler, ADDU_W | SA(RETURN_ADDR_REG) | TA(0) | D(dst), UNMOVABLE_INS);
+ }
break;
case SLJIT_GET_RETURN_ADDRESS:
dst_ar = DR(FAST_IS_REG(dst) ? dst : TMP_REG2);
@@ -3278,6 +3349,60 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, i;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (alignment <= SLJIT_LABEL_ALIGN_4) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);
+
+ for (i = (mask >> 2); i != 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ for (i = (buffers->size + 3) >> 2; i > 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS));
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
#define BRANCH_LENGTH 4
#else
@@ -3718,7 +3843,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
static sljit_ins get_select_cc(sljit_s32 type, sljit_s32 is_float)
{
- switch (type & ~SLJIT_32) {
+ switch (type) {
case SLJIT_EQUAL:
return (is_float ? MOVZ_S : MOVZ) | TA(EQUAL_FLAG);
case SLJIT_NOT_EQUAL:
@@ -3789,15 +3914,37 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
ADJUST_LOCAL_OFFSET(src1, src1w);
+#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
+ if (src1 == SLJIT_IMM && (type & SLJIT_32))
+ src1w = (sljit_s32)src1w;
+#endif
+
+ type &= ~SLJIT_32;
+
+ if (type & SLJIT_COMPARE_SELECT) {
+ type ^= SLJIT_COMPARE_SELECT;
+
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
+ src1 = TMP_REG1;
+ } else if (src1 == SLJIT_IMM) {
+ if (src1w == 0) {
+ src1 = 0;
+ } else {
+ FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
+ src1 = TMP_REG1;
+ }
+ }
+
+ src1w = 0;
+ FAIL_IF(emit_op(compiler, SLJIT_SUB | SLJIT_SET(type & ~0x1), IMM_OP, 0, 0, src1, 0, src2_reg, 0));
+ }
+
#if (defined SLJIT_MIPS_REV && SLJIT_MIPS_REV >= 1 && SLJIT_MIPS_REV < 6)
if (src1 & SLJIT_MEM) {
FAIL_IF(emit_op_mem(compiler, inp_flags, DR(TMP_REG1), src1, src1w));
src1 = TMP_REG1;
} else if (src1 == SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (type & SLJIT_32)
- src1w = (sljit_s32)src1w;
-#endif
FAIL_IF(load_immediate(compiler, DR(TMP_REG1), src1w));
src1 = TMP_REG1;
}
@@ -3834,16 +3981,12 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
}
SLJIT_SKIP_CHECKS(compiler);
- jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1);
+ jump = sljit_emit_jump(compiler, type ^ 0x1);
FAIL_IF(!jump);
if (src1 & SLJIT_MEM) {
FAIL_IF(emit_op_mem(compiler, inp_flags, DR(dst_reg), src1, src1w));
} else if (src1 == SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
- if (type & SLJIT_32)
- src1w = (sljit_s32)src1w;
-#endif /* SLJIT_CONFIG_MIPS_64 */
FAIL_IF(load_immediate(compiler, DR(dst_reg), src1w));
} else
FAIL_IF(push_inst(compiler, mov_ins | S(src1) | TA(0) | D(dst_reg), DR(dst_reg)));
@@ -3887,11 +4030,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
src1 = TMP_FREG2;
}
- return push_inst(compiler, get_select_cc(type, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS);
+ return push_inst(compiler, get_select_cc(type & ~SLJIT_32, 1) | FMT(type) | FS(src1) | FD(dst_freg), MOVABLE_INS);
#else /* SLJIT_MIPS_REV < 1 || SLJIT_MIPS_REV >= 6 */
SLJIT_SKIP_CHECKS(compiler);
- jump = sljit_emit_jump(compiler, (type & ~SLJIT_32) ^ 0x1);
+ jump = sljit_emit_jump(compiler, type ^ 0x1);
FAIL_IF(!jump);
if (src1 & SLJIT_MEM)
@@ -4301,7 +4444,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
#if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64)
ins = SCD;
break;
-#endif /* SLJIT_CONFIG_RISCV_64 */
+#endif /* SLJIT_CONFIG_MIPS_64 */
case SLJIT_MOV_S32:
case SLJIT_MOV32:
op |= SLJIT_32;
@@ -4319,13 +4462,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
return push_inst(compiler, ins | TA(OTHER_FLAG) | S(mem_reg), OTHER_FLAG);
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
struct sljit_const *const_;
sljit_s32 dst_r;
+ sljit_s32 mem_flags = WORD_DATA;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
@@ -4333,37 +4479,119 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
set_const(const_, compiler);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ if (init_value & 0x100)
+ init_value |= 0xff00;
+ else
+ init_value &= 0xff;
+
+ PTR_FAIL_IF(push_inst(compiler, ADDIU | SA(0) | T(dst_r) | IMM(init_value), DR(dst_r)));
+ mem_flags = BYTE_DATA;
+ break;
+
+#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64)
+ case SLJIT_MOV32:
+ mem_flags = INT_DATA;
+ SLJIT_FALLTHROUGH
+ case SLJIT_MOV_S32:
+ PTR_FAIL_IF(push_inst(compiler, LUI | T(dst_r) | IMM(init_value >> 16), DR(dst_r)));
+ PTR_FAIL_IF(push_inst(compiler, ORI | S(dst_r) | T(dst_r) | IMM(init_value), DR(dst_r)));
+ break;
+#endif /* SLJIT_CONFIG_MIPS_64 */
+
+ default:
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
+ break;
+ }
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
+ PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, DR(TMP_REG2), dst, dstw));
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_s32 dst_r;
+ sljit_s32 dst_r, target_r;
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = TMP_REG1;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, DR(TMP_REG2), dst, dstw));
+ }
+
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF(!jump);
set_mov_addr(jump, compiler, 0);
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r, UNMOVABLE_INS));
+ PTR_FAIL_IF(push_inst(compiler, (sljit_ins)target_r, UNMOVABLE_INS));
#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32)
compiler->size += 1;
#else
compiler->size += 5;
#endif
+ if (op == SLJIT_ADD_ABS_ADDR)
+ PTR_FAIL_IF(push_inst(compiler, ADDU_W | S(dst_r) | T(TMP_REG1) | D(dst_r), DR(dst_r)));
+
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, DR(TMP_REG2), dst, dstw));
return jump;
}
+
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
+{
+ sljit_ins *inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xfc000000) == ADDIU);
+
+ if (new_constant & 0x100)
+ new_constant |= 0xff00;
+ else
+ new_constant &= 0xff;
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ inst[0] = (inst[0] & 0xffff0000) | IMM(new_constant);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ return;
+
+#if (defined(SLJIT_CONFIG_MIPS_64) && SLJIT_CONFIG_MIPS_64)
+ case SLJIT_MOV32:
+ case SLJIT_MOV_S32:
+ inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xffe00000) == LUI && (inst[1] & 0xfc000000) == ORI);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ inst[0] = (inst[0] & 0xffff0000) | IMM(new_constant >> 16);
+ inst[1] = (inst[1] & 0xffff0000) | IMM(new_constant);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ return;
+#endif /* SLJIT_CONFIG_MIPS_64 */
+
+ default:
+ sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ return;
+ }
+}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_32.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_32.c
index 2352fad5d47..c07f4b48e04 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_32.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_32.c
@@ -477,8 +477,8 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
- inst[0] = (inst[0] & 0xffff0000) | ((new_target >> 16) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000) | (new_target & 0xffff);
+ inst[0] = (inst[0] & 0xffff0000) | IMM(new_target >> 16);
+ inst[1] = (inst[1] & 0xffff0000) | IMM(new_target);
SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 2);
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_64.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_64.c
index b3cf9d074d5..2b07fcba47f 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_64.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_64.c
@@ -709,10 +709,10 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_UNUSED_ARG(executable_offset);
SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
- inst[0] = (inst[0] & 0xffff0000u) | ((sljit_ins)(new_target >> 48) & 0xffff);
- inst[1] = (inst[1] & 0xffff0000u) | ((sljit_ins)(new_target >> 32) & 0xffff);
- inst[3] = (inst[3] & 0xffff0000u) | ((sljit_ins)(new_target >> 16) & 0xffff);
- inst[4] = (inst[4] & 0xffff0000u) | ((sljit_ins)new_target & 0xffff);
+ inst[0] = (inst[0] & 0xffff0000u) | IMM(new_target >> 48);
+ inst[1] = (inst[1] & 0xffff0000u) | IMM(new_target >> 32);
+ inst[3] = (inst[3] & 0xffff0000u) | IMM(new_target >> 16);
+ inst[4] = (inst[4] & 0xffff0000u) | IMM(new_target);
SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
SLJIT_CACHE_FLUSH(inst, inst + 5);
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_common.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_common.c
index 3d2268e896b..07df86f3156 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_common.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativePPC_common.c
@@ -113,7 +113,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = {
};
/* --------------------------------------------------------------------- */
-/* Instrucion forms */
+/* Instruction forms */
/* --------------------------------------------------------------------- */
#define D(d) ((sljit_ins)reg_map[d] << 21)
#define S(s) ((sljit_ins)reg_map[s] << 21)
@@ -504,6 +504,12 @@ static void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executab
#endif /* SLJIT_CONFIG_PPC_32 */
}
+static SLJIT_INLINE sljit_ins *process_extended_label(sljit_ins *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_ins*)((sljit_uw)code_ptr & ~(ext_label->data));
+}
+
static void reduce_code_size(struct sljit_compiler *compiler)
{
struct sljit_label *label;
@@ -619,18 +625,20 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reduce_code_size(compiler);
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+ if (!(options & SLJIT_GENERATE_CODE_NO_CONTEXT)) {
/* add to compiler->size additional instruction space to hold the trampoline and padding */
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
-#else
- compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
-#endif
-#endif
+ compiler->size += (compiler->size & 0x1) + (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
+#else /* !SLJIT_CONFIG_PPC_64 */
+ compiler->size += (sizeof(struct sljit_function_context) / sizeof(sljit_ins));
+#endif /* SLJIT_CONFIG_PPC_64 */
+ }
+#endif /* SLJIT_INDIRECT_CALL */
code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
PTR_FAIL_WITH_EXEC_IF(code);
@@ -657,6 +665,11 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
/* These structures are ordered by their address. */
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+ *code_ptr = buf_ptr[-1];
+ }
+
/* Just recording the address. */
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
@@ -700,6 +713,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} while (buf);
if (label && label->size == word_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -710,7 +726,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!const_);
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
- SLJIT_ASSERT(code_ptr - code <= (sljit_sw)(compiler->size - (sizeof(struct sljit_function_context) / sizeof(sljit_ins))));
+ SLJIT_ASSERT(code_ptr - code <= (sljit_sw)(compiler->size -
+ ((options & SLJIT_GENERATE_CODE_NO_CONTEXT) ? 0 : (sizeof(struct sljit_function_context) / sizeof(sljit_ins)))));
#else
SLJIT_ASSERT(code_ptr - code <= (sljit_sw)compiler->size);
#endif
@@ -727,12 +744,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
+ if (!(options & SLJIT_GENERATE_CODE_NO_CONTEXT)) {
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
- if (((sljit_sw)code_ptr) & 0x4)
- code_ptr++;
-#endif
- sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_uw)code, (void*)sljit_generate_code);
-#endif
+ if (((sljit_sw)code_ptr) & 0x4)
+ code_ptr++;
+#endif /* SLJIT_CONFIG_PPC_64 */
+ sljit_set_function_context(NULL, (struct sljit_function_context*)code_ptr, (sljit_uw)code, (void*)sljit_generate_code);
+ }
+#endif /* SLJIT_INDIRECT_CALL */
code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
@@ -740,12 +759,14 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
#if (defined SLJIT_INDIRECT_CALL && SLJIT_INDIRECT_CALL)
- compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins) + sizeof(struct sljit_function_context);
- return code_ptr;
-#else
+ if (!(options & SLJIT_GENERATE_CODE_NO_CONTEXT)) {
+ compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins) + sizeof(struct sljit_function_context);
+ return code_ptr;
+ }
+#endif /* SLJIT_INDIRECT_CALL */
+
compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
return code;
-#endif
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
@@ -1683,7 +1704,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
op |= SLJIT_32;
#endif /* SLJIT_CONFIG_PPC_64 */
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_REV:
case SLJIT_REV_U16:
case SLJIT_REV_S16:
@@ -1925,7 +1946,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2(struct sljit_compiler *compile
if (src1 == SLJIT_IMM && src1w == -1) {
return emit_op(compiler, GET_OPCODE(op), flags | ALT_FORM4, dst, dstw, TMP_REG1, 0, src2, src2w);
}
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_AND:
case SLJIT_OR:
/* Commutative unsigned operations. */
@@ -2103,6 +2124,56 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst(compiler, OR | S(dst_reg) | A(dst_reg) | B(TMP_REG1));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r, tmp_r;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+ src1 = TMP_REG1;
+ } else if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src1, src1w, TMP_REG1));
+ src1 = TMP_REG1;
+ }
+
+ tmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, tmp_r, src2, src2w, tmp_r));
+ src2 = tmp_r;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ FAIL_IF(push_inst(compiler, SLWI_W(shift_arg) | S(src2) | A(tmp_r)));
+ FAIL_IF(push_inst(compiler, ADD | D(dst_r) | A(src1) | B(tmp_r)));
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem(compiler, WORD_DATA, dst_r, dst, dstw, TMP_REG1);
+ return SLJIT_SUCCESS;
+}
+
static sljit_s32 emit_prefetch(struct sljit_compiler *compiler,
sljit_s32 src, sljit_sw srcw)
{
@@ -2322,7 +2393,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compil
FAIL_IF(push_inst(compiler, FRSP | FD(dst_r) | FB(src)));
break;
}
- /* Fall through. */
+ SLJIT_FALLTHROUGH
case SLJIT_MOV_F64:
if (src != dst_r) {
if (!(dst & SLJIT_MEM))
@@ -2447,13 +2518,67 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, i;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (alignment <= SLJIT_LABEL_ALIGN_4) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);
+
+ for (i = (mask >> 2); i != 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ for (i = (buffers->size + 3) >> 2; i > 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type)
{
switch (type) {
case SLJIT_NOT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
return (4 << 21) | (2 << 16);
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_EQUAL:
case SLJIT_ATOMIC_STORED:
@@ -2462,7 +2587,7 @@ static sljit_ins get_bo_bi_flags(struct sljit_compiler *compiler, sljit_s32 type
case SLJIT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
return (12 << 21) | (2 << 16);
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_NOT_EQUAL:
case SLJIT_ATOMIC_NOT_STORED:
@@ -2835,6 +2960,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
{
sljit_ins *ptr;
sljit_uw size;
+ sljit_s32 is_compare = (type & SLJIT_COMPARE_SELECT);
+ sljit_ins ins;
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
#else /* !SLJIT_CONFIG_PPC_64 */
@@ -2846,6 +2973,45 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
ADJUST_LOCAL_OFFSET(src1, src1w);
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (src1 == SLJIT_IMM && (type & SLJIT_32))
+ src1w = (sljit_s32)src1w;
+#endif /* SLJIT_CONFIG_PPC_64 */
+
+ type &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);
+
+ if (is_compare) {
+ ins = 0;
+
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w, TMP_REG1));
+ src1 = TMP_REG1;
+ src1w = 0;
+ }
+
+ if (src1 == SLJIT_IMM) {
+ if (type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL && src1w >= 0 && src1w <= UIMM_MAX)
+ ins = CMPLI | CRD(0) | IMM(src1w);
+ else if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL && src1w >= SIMM_MIN && src1w <= SIMM_MAX)
+ ins = CMPI | CRD(0) | IMM(src1w);
+ else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w));
+ src1 = TMP_REG1;
+ src1w = 0;
+ }
+ }
+
+ if (ins == 0)
+ ins = ((type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL) ? CMPL : CMP) | CRD(0) | B(src1);
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ if (inp_flags == (WORD_DATA | LOAD_DATA))
+ ins |= CRD(1);
+#endif /* SLJIT_CONFIG_PPC_64 */
+ FAIL_IF(push_inst(compiler, ins | A(src2_reg)));
+ type ^= 0x1;
+ }
+
if (dst_reg != src2_reg) {
if (dst_reg == src1) {
src1 = src2_reg;
@@ -2866,7 +3032,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
}
}
- if (((type & ~SLJIT_32) | 0x1) == SLJIT_NOT_CARRY)
+ if ((type | 0x1) == SLJIT_NOT_CARRY)
FAIL_IF(push_inst(compiler, ADDE | RC(ALT_SET_FLAGS) | D(TMP_REG1) | A(TMP_ZERO) | B(TMP_ZERO)));
size = compiler->size;
@@ -2878,15 +3044,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
if (src1 & SLJIT_MEM) {
FAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w, TMP_REG1));
} else if (src1 == SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (type & SLJIT_32)
- src1w = (sljit_s32)src1w;
-#endif /* SLJIT_CONFIG_RISCV_64 */
FAIL_IF(load_immediate(compiler, dst_reg, src1w));
} else
FAIL_IF(push_inst(compiler, OR | S(src1) | A(dst_reg) | B(src1)));
- *ptr = BCx | get_bo_bi_flags(compiler, (type ^ 0x1) & ~SLJIT_32) | (sljit_ins)((compiler->size - size) << 2);
+ *ptr = BCx | get_bo_bi_flags(compiler, type ^ 0x1) | (sljit_ins)((compiler->size - size) << 2);
return SLJIT_SUCCESS;
}
@@ -3162,7 +3324,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
ins = LDARX;
break;
-#endif /* SLJIT_CONFIG_RISCV_64 */
+#endif /* SLJIT_CONFIG_PPC_64 */
case SLJIT_MOV_U32:
case SLJIT_MOV32:
ins = LWARX;
@@ -3200,7 +3362,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
ins = STDCX | 0x1;
break;
-#endif /* SLJIT_CONFIG_RISCV_64 */
+#endif /* SLJIT_CONFIG_PPC_64 */
case SLJIT_MOV_U32:
case SLJIT_MOV32:
ins = STWCX | 0x1;
@@ -3216,13 +3378,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
return push_inst(compiler, ins | D(src_reg) | B(mem_reg));
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
struct sljit_const *const_;
sljit_s32 dst_r;
+ sljit_s32 mem_flags = WORD_DATA;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
@@ -3230,42 +3395,119 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
set_const(const_, compiler);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ if (init_value & 0x100)
+ init_value |= 0xff00;
+ else
+ init_value &= 0xff;
+
+ PTR_FAIL_IF(push_inst(compiler, ADDI | D(dst_r) | A(0) | IMM(init_value)));
+ mem_flags = BYTE_DATA;
+ break;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ case SLJIT_MOV32:
+ mem_flags = INT_DATA;
+ SLJIT_FALLTHROUGH
+ case SLJIT_MOV_S32:
+ PTR_FAIL_IF(push_inst(compiler, ADDIS | D(dst_r) | A(0) | IMM(init_value >> 16)));
+ PTR_FAIL_IF(push_inst(compiler, ORI | S(dst_r) | A(dst_r) | IMM(init_value)));
+ break;
+#endif /* SLJIT_CONFIG_PPC_64 */
+
+ default:
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value));
+ break;
+ }
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_r, dst, dstw, TMP_REG1));
+ PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, dst_r, dst, dstw, TMP_REG1));
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_s32 dst_r;
+ sljit_s32 dst_r, target_r;
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = TMP_REG1;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, dst_r, dst, dstw, TMP_REG1));
+ }
+
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF(!jump);
set_mov_addr(jump, compiler, 0);
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
+ PTR_FAIL_IF(push_inst(compiler, (sljit_ins)target_r));
#if (defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32)
compiler->size++;
#else
compiler->size += 4;
#endif
+ if (op == SLJIT_ADD_ABS_ADDR)
+ PTR_FAIL_IF(push_inst(compiler, ADD | D(dst_r) | A(dst_r) | B(TMP_REG1)));
+
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op(compiler, SLJIT_MOV, WORD_DATA, dst, dstw, TMP_REG1, 0, TMP_REG2, 0));
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, dst_r, dst, dstw, TMP_REG1));
return jump;
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ sljit_ins *inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDI);
+
+ if (new_constant & 0x100)
+ new_constant |= 0xff00;
+ else
+ new_constant &= 0xff;
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 0);
+ inst[0] = (inst[0] & 0xffff0000) | IMM(new_constant);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 1, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 1);
+ return;
+
+#if (defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64)
+ case SLJIT_MOV32:
+ case SLJIT_MOV_S32:
+ inst = (sljit_ins *)addr;
+ SLJIT_ASSERT((inst[0] & 0xfc1f0000) == ADDIS && (inst[1] & 0xfc000000) == ORI);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ inst[0] = (inst[0] & 0xffff0000) | IMM(new_constant >> 16);
+ inst[1] = (inst[1] & 0xffff0000) | IMM(new_constant);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
+ inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ return;
+#endif /* SLJIT_CONFIG_PPC_64 */
+
+ default:
+ sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ return;
+ }
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_32.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_32.c
index 396c956c197..e2dfb01cd07 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_32.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_32.c
@@ -28,17 +28,28 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
{
SLJIT_UNUSED_ARG(tmp_r);
+ if (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN)
+ return push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm));
+
if (imm <= SIMM_MAX && imm >= SIMM_MIN)
return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
if (imm & 0x800)
imm += 0x1000;
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
+ if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000)
+ FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));
+ else
+ FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~(sljit_sw)0xfff)));
+
+ imm &= 0xfff;
- if ((imm & 0xfff) == 0)
+ if (imm == 0)
return SLJIT_SUCCESS;
+ if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))
+ return push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm));
+
return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
}
@@ -123,20 +134,21 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins*)addr;
+ sljit_u16 *inst = (sljit_u16*)addr;
SLJIT_UNUSED_ARG(executable_offset);
if ((new_target & 0x800) != 0)
new_target += 0x1000;
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
SLJIT_ASSERT((inst[0] & 0x7f) == LUI);
- inst[0] = (inst[0] & 0xfff) | (sljit_ins)((sljit_sw)new_target & ~0xfff);
- SLJIT_ASSERT((inst[1] & 0x707f) == ADDI || (inst[1] & 0x707f) == JALR);
- inst[1] = (inst[1] & 0xfffff) | IMM_I(new_target);
-
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 5);
+ inst[0] = (sljit_u16)((inst[0] & 0xfff) | (new_target & 0xf000));
+ inst[1] = (sljit_u16)(new_target >> 16);
+ SLJIT_ASSERT((inst[2] & 0x707f) == ADDI || (inst[2] & 0x707f) == JALR);
+ inst[3] = (sljit_u16)((inst[3] & 0xf) | (new_target << 4));
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
+ inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 4);
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_64.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_64.c
index 7fcf2c52730..113d1f88702 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_64.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_64.c
@@ -24,29 +24,88 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)
+static sljit_s32 load_immediate32(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm)
{
- sljit_sw high;
+ SLJIT_ASSERT((imm <= 0x7fffffffl && imm > SIMM_MAX) || (imm >= S32_MIN && imm < SIMM_MIN));
- if (imm <= SIMM_MAX && imm >= SIMM_MIN)
- return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
+ if (imm > S32_MAX) {
+ SLJIT_ASSERT((imm & 0x800) != 0);
+ FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
+ return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
+ }
- if (imm <= 0x7fffffffl && imm >= S32_MIN) {
- if (imm > S32_MAX) {
+ if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000) {
+ if (imm > 0x1f7ff) {
SLJIT_ASSERT((imm & 0x800) != 0);
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
+ FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | (sljit_u16)0x1000));
return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
}
if ((imm & 0x800) != 0)
imm += 0x1000;
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
+ FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));
+ } else {
+ if ((imm & 0x800) != 0)
+ imm += 0x1000;
+
+ FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~(sljit_sw)0xfff)));
+ }
+
+ imm &= 0xfff;
+
+ if (imm == 0)
+ return SLJIT_SUCCESS;
+
+ if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))
+ return push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm));
+
+ return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
+}
+
+static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r, sljit_sw imm, sljit_s32 tmp_r)
+{
+ sljit_sw high, shift;
+
+ if (RISCV_HAS_COMPRESSED(200) && imm <= SIMM16_MAX && imm >= SIMM16_MIN)
+ return push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm));
- if ((imm & 0xfff) == 0)
- return SLJIT_SUCCESS;
+ if (imm <= SIMM_MAX && imm >= SIMM_MIN)
+ return push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm));
+
+ if (imm <= 0x7fffffffl && imm >= S32_MIN)
+ return load_immediate32(compiler, dst_r, imm);
+
+ /* Shifted small immediates. */
+
+ high = imm;
+ shift = 0;
+ while ((high & 0xff) == 0) {
+ high >>= 8;
+ shift += 8;
+ }
+
+ if ((high & 0xf) == 0) {
+ high >>= 4;
+ shift += 4;
+ }
+
+ if ((high & 0x3) == 0) {
+ high >>= 2;
+ shift += 2;
+ }
+
+ if ((high & 0x1) == 0) {
+ high >>= 1;
+ shift += 1;
+ }
+
+ if (high <= 0x7fffffffl && high >= S32_MIN) {
+ load_immediate(compiler, dst_r, high, tmp_r);
- return push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
+ if (RISCV_HAS_COMPRESSED(200))
+ return push_inst16(compiler, C_SLLI | C_RD(dst_r) | C_IMM_I(shift));
+ return push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(shift));
}
/* Trailing zeroes could be used to produce shifted immediates. */
@@ -57,26 +116,15 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
if (imm & 0x800)
high = ~high;
- if (high > S32_MAX) {
- SLJIT_ASSERT((high & 0x800) != 0);
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)0x80000000u));
- FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(high)));
- } else {
- if ((high & 0x800) != 0)
- high += 0x1000;
-
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(high & ~0xfff)));
+ FAIL_IF(load_immediate32(compiler, dst_r, high));
- if ((high & 0xfff) != 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(high)));
- }
-
- FAIL_IF(push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(12)));
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_SLLI | C_RD(dst_r) | (sljit_u16)(12 << 2)));
+ else
+ FAIL_IF(push_inst(compiler, SLLI | RD(dst_r) | RS1(dst_r) | IMM_I(12)));
- if ((imm & 0xfff) != 0)
- return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
-
- return SLJIT_SUCCESS;
+ SLJIT_ASSERT((imm & 0xfff) != 0);
+ return push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm));
}
SLJIT_ASSERT(dst_r != tmp_r);
@@ -99,7 +147,10 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
}
if (imm <= SIMM_MAX && imm >= SIMM_MIN) {
- FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)));
+ if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1f && imm >= -0x20)
+ FAIL_IF(push_inst16(compiler, C_LI | C_RD(dst_r) | C_IMM_I(imm)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(TMP_ZERO) | IMM_I(imm)));
imm = 0;
} else if (imm > S32_MAX) {
SLJIT_ASSERT((imm & 0x800) != 0);
@@ -110,19 +161,35 @@ static sljit_s32 load_immediate(struct sljit_compiler *compiler, sljit_s32 dst_r
if ((imm & 0x800) != 0)
imm += 0x1000;
- FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
+ if (RISCV_HAS_COMPRESSED(200) && imm <= 0x1ffff && imm >= -0x20000)
+ FAIL_IF(push_inst16(compiler, C_LUI | C_RD(dst_r) | ((sljit_u16)(((imm) & 0x1f000) >> 10) | ((imm) & 0x20000) >> 5)));
+ else
+ FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(imm & ~0xfff)));
imm &= 0xfff;
}
- if ((high & 0xfff) != 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high)));
+ if ((high & 0xfff) != 0) {
+ SLJIT_ASSERT(high <= 0xfff);
+ if (RISCV_HAS_COMPRESSED(200) && (high <= 0x1f || high >= 0xfe0))
+ FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(tmp_r) | C_IMM_I(high)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(tmp_r) | RS1(tmp_r) | IMM_I(high)));
+ }
if (imm & 0x1000)
FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
- else if (imm != 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
+ else if (imm != 0) {
+ SLJIT_ASSERT(imm <= 0xfff);
+ if (RISCV_HAS_COMPRESSED(200) && (imm <= 0x1f || imm >= 0xfe0))
+ FAIL_IF(push_inst16(compiler, C_ADDI | C_RD(dst_r) | C_IMM_I(imm)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | RS1(dst_r) | IMM_I(imm)));
+ }
- FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(tmp_r) | IMM_I((high & 0x1000) ? 20 : 32)));
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_SLLI | C_RD(tmp_r) | (sljit_u16)((high & 0x1000) ? (20 << 2) : (1 << 12))));
+ else
+ FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(tmp_r) | IMM_I((high & 0x1000) ? 20 : 32)));
return push_inst(compiler, XOR | RD(dst_r) | RS1(dst_r) | RS2(tmp_r));
}
@@ -190,7 +257,7 @@ static SLJIT_INLINE sljit_s32 emit_const(struct sljit_compiler *compiler, sljit_
SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_target, sljit_sw executable_offset)
{
- sljit_ins *inst = (sljit_ins*)addr;
+ sljit_u16 *inst = (sljit_u16*)addr;
sljit_sw high;
SLJIT_UNUSED_ARG(executable_offset);
@@ -205,18 +272,20 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
if ((high & 0x800) != 0)
high += 0x1000;
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 0);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 12, 0);
SLJIT_ASSERT((inst[0] & 0x7f) == LUI);
- inst[0] = (inst[0] & 0xfff) | (sljit_ins)(high & ~0xfff);
- SLJIT_ASSERT((inst[1] & 0x707f) == ADDI);
- inst[1] = (inst[1] & 0xfffff) | IMM_I(high);
- SLJIT_ASSERT((inst[2] & 0x7f) == LUI);
- inst[2] = (inst[2] & 0xfff) | (sljit_ins)((sljit_sw)new_target & ~0xfff);
- SLJIT_ASSERT((inst[5] & 0x707f) == ADDI || (inst[5] & 0x707f) == JALR);
- inst[5] = (inst[5] & 0xfffff) | IMM_I(new_target);
- SLJIT_UPDATE_WX_FLAGS(inst, inst + 5, 1);
-
- inst = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
- SLJIT_CACHE_FLUSH(inst, inst + 5);
+ inst[0] = (sljit_u16)((inst[0] & 0xfff) | (high & 0xf000));
+ inst[1] = (sljit_u16)(high >> 16);
+ SLJIT_ASSERT((inst[2] & 0x707f) == ADDI);
+ inst[3] = (sljit_u16)((inst[3] & 0xf) | (high << 4));
+ SLJIT_ASSERT((inst[4] & 0x7f) == LUI);
+ inst[4] = (sljit_u16)((inst[4] & 0xfff) | (new_target & 0xf000));
+ inst[5] = (sljit_u16)(new_target >> 16);
+ SLJIT_ASSERT((inst[10] & 0x707f) == ADDI || (inst[10] & 0x707f) == JALR);
+ inst[11] = (sljit_u16)((inst[11] & 0xf) | (new_target << 4));
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 12, 1);
+
+ inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 12);
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_common.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_common.c
index d3ba46dba8b..dec12c9a67f 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_common.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeRISCV_common.c
@@ -24,17 +24,148 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#if !(defined SLJIT_CONFIG_RISCV_ATOMIC) && defined(__riscv_atomic)
+/* Auto detect atomic instruction support. */
+#define SLJIT_CONFIG_RISCV_ATOMIC 200
+#endif /* !SLJIT_CONFIG_RISCV_ATOMIC && __riscv_atomic */
+
+/* SLJIT_CONFIG_RISCV_ATOMIC enables/disables atomic instruction
+ support. Non-zero values represents the highest version of the feature
+ that is supported by the CPU.
+ Allowed values: 0 - disabled, 200 - 2.00 */
+#if (defined SLJIT_CONFIG_RISCV_ATOMIC && SLJIT_CONFIG_RISCV_ATOMIC != 0)
+#if SLJIT_CONFIG_RISCV_ATOMIC != 200
+#error "Unsupported value for SLJIT_CONFIG_RISCV_ATOMIC"
+#endif
+#define RISCV_HAS_ATOMIC(x) ((SLJIT_CONFIG_RISCV_ATOMIC) >= (x))
+#define RISCV_ATOMIC_INFO "a"
+#else /* !SLJIT_CONFIG_RISCV_ATOMIC || SLJIT_CONFIG_RISCV_ATOMIC == 0 */
+#define RISCV_HAS_ATOMIC(x) 0
+#define RISCV_ATOMIC_INFO ""
+#endif /* SLJIT_CONFIG_RISCV_ATOMIC && SLJIT_CONFIG_RISCV_ATOMIC != 0 */
+
+#if !(defined SLJIT_CONFIG_RISCV_COMPRESSED) && defined(__riscv_compressed)
+/* Auto detect compressed instruction support. */
+#define SLJIT_CONFIG_RISCV_COMPRESSED 200
+#endif /* !SLJIT_CONFIG_RISCV_COMPRESSED && __riscv_compressed */
+
+/* SLJIT_CONFIG_RISCV_COMPRESSED enables/disables compressed instruction
+ support. Non-zero values represents the highest version of the feature
+ that is supported by the CPU.
+ Allowed values: 0 - disabled, 200 - 2.00 */
+#if (defined SLJIT_CONFIG_RISCV_COMPRESSED && SLJIT_CONFIG_RISCV_COMPRESSED != 0)
+#if SLJIT_CONFIG_RISCV_COMPRESSED != 200
+#error "Unsupported value for SLJIT_CONFIG_RISCV_COMPRESSED"
+#endif
+#define RISCV_HAS_COMPRESSED(x) ((SLJIT_CONFIG_RISCV_COMPRESSED) >= (x))
+#define RISCV_COMPRESSED_CHECK(x) (x)
+#define RISCV_COMPRESSED_INFO "c"
+#else /* !SLJIT_CONFIG_RISCV_COMPRESSED || SLJIT_CONFIG_RISCV_COMPRESSED == 0 */
+#define RISCV_HAS_COMPRESSED(x) 0
+#define RISCV_COMPRESSED_CHECK(x) 0
+#define RISCV_COMPRESSED_INFO ""
+#endif /* SLJIT_CONFIG_RISCV_COMPRESSED && SLJIT_CONFIG_RISCV_COMPRESSED != 0 */
+
+#if !(defined SLJIT_CONFIG_RISCV_VECTOR) && defined(__riscv_vector)
+/* Auto detect vector instruction support. */
+#define SLJIT_CONFIG_RISCV_VECTOR 100
+#endif /* !SLJIT_CONFIG_RISCV_VECTOR && __riscv_vector */
+
+/* SLJIT_CONFIG_RISCV_VECTOR enables/disables vector instruction
+ support. Non-zero values represents the highest version of the feature
+ that is supported by the CPU.
+ Allowed values: 0 - disabled, 100 - 1.00 */
+#if (defined SLJIT_CONFIG_RISCV_VECTOR && SLJIT_CONFIG_RISCV_VECTOR != 0)
+#if SLJIT_CONFIG_RISCV_VECTOR != 100
+#error "Unsupported value for SLJIT_CONFIG_RISCV_VECTOR"
+#endif
+#define RISCV_HAS_VECTOR(x) ((SLJIT_CONFIG_RISCV_VECTOR) >= (x))
+#define RISCV_VECTOR_INFO "v"
+#else /* !SLJIT_CONFIG_RISCV_VECTOR || SLJIT_CONFIG_RISCV_VECTOR == 0 */
+#define RISCV_HAS_VECTOR(x) 0
+#define RISCV_VECTOR_INFO ""
+#endif /* SLJIT_CONFIG_RISCV_VECTOR && SLJIT_CONFIG_RISCV_VECTOR != 0 */
+
+#if !(defined SLJIT_CONFIG_RISCV_BITMANIP_A) && defined(__riscv_zba)
+/* Auto detect bit manipulation extension A instruction support. */
+#define SLJIT_CONFIG_RISCV_BITMANIP_A 93
+#endif /* !SLJIT_CONFIG_RISCV_BITMANIP_A && __riscv_zba */
+
+/* SLJIT_CONFIG_RISCV_BITMANIP_A enables/disables bit manipulation extension A
+ instruction support. Non-zero values represents the highest version of the
+ feature that is supported by the CPU.
+ Allowed values: 0 - disabled, 93 - 0.93 */
+#if (defined SLJIT_CONFIG_RISCV_BITMANIP_A && SLJIT_CONFIG_RISCV_BITMANIP_A != 0)
+#if SLJIT_CONFIG_RISCV_BITMANIP_A != 93
+#error "Unsupported value for SLJIT_CONFIG_RISCV_BITMANIP_A"
+#endif
+#define RISCV_HAS_BITMANIP_A(x) ((SLJIT_CONFIG_RISCV_BITMANIP_A) >= (x))
+#define RISCV_BITMANIP_A_INFO "_zba"
+#else /* !SLJIT_CONFIG_RISCV_BITMANIP_A || SLJIT_CONFIG_RISCV_BITMANIP_A == 0 */
+#define RISCV_HAS_BITMANIP_A(x) 0
+#define RISCV_BITMANIP_A_INFO ""
+#endif /* SLJIT_CONFIG_RISCV_BITMANIP_A && SLJIT_CONFIG_RISCV_BITMANIP_A != 0 */
+
+#if !(defined SLJIT_CONFIG_RISCV_BITMANIP_B) && defined(__riscv_zbb)
+/* Auto detect bit manipulation extension B instruction support. */
+#define SLJIT_CONFIG_RISCV_BITMANIP_B 93
+#endif /* !SLJIT_CONFIG_RISCV_BITMANIP_B && __riscv_zbb */
+
+/* SLJIT_CONFIG_RISCV_BITMANIP_B enables/disables bit manipulation extension B
+ instruction support. Non-zero values represents the highest version of the
+ feature that is supported by the CPU.
+ Allowed values: 0 - disabled, 93 - 0.93 */
+#if (defined SLJIT_CONFIG_RISCV_BITMANIP_B && SLJIT_CONFIG_RISCV_BITMANIP_B != 0)
+#if SLJIT_CONFIG_RISCV_BITMANIP_B != 93
+#error "Unsupported value for SLJIT_CONFIG_RISCV_BITMANIP_B"
+#endif
+#define RISCV_HAS_BITMANIP_B(x) ((SLJIT_CONFIG_RISCV_BITMANIP_B) >= (x))
+#define RISCV_BITMANIP_B_INFO "_zbb"
+#else /* !SLJIT_CONFIG_RISCV_BITMANIP_B || SLJIT_CONFIG_RISCV_BITMANIP_B == 0 */
+#define RISCV_HAS_BITMANIP_B(x) 0
+#define RISCV_BITMANIP_B_INFO ""
+#endif /* SLJIT_CONFIG_RISCV_BITMANIP_B && SLJIT_CONFIG_RISCV_BITMANIP_B != 0 */
+
+#if !(defined SLJIT_CONFIG_RISCV_ICOND) && defined(__riscv_zicond)
+/* Auto detect integer conditional instruction support. */
+#define SLJIT_CONFIG_RISCV_ICOND 100
+#endif /* !SLJIT_CONFIG_RISCV_ICOND && __riscv_zicond */
+
+/* SLJIT_CONFIG_RISCV_ICOND enables/disables integer conditional
+ instruction support. Non-zero values represents the highest version of the
+ feature that is supported by the CPU.
+ Allowed values: 0 - disabled, 100 - 1.00 */
+#if (defined SLJIT_CONFIG_RISCV_ICOND && SLJIT_CONFIG_RISCV_ICOND != 0)
+#if SLJIT_CONFIG_RISCV_ICOND != 100
+#error "Unsupported value for SLJIT_CONFIG_RISCV_ICOND"
+#endif
+#define RISCV_HAS_ICOND(x) ((SLJIT_CONFIG_RISCV_ICOND) >= (x))
+#define RISCV_ICOND_INFO "_zicond"
+#else /* !SLJIT_CONFIG_RISCV_ICOND || SLJIT_CONFIG_RISCV_ICOND == 0 */
+#define RISCV_HAS_ICOND(x) 0
+#define RISCV_ICOND_INFO ""
+#endif /* SLJIT_CONFIG_RISCV_ICOND && SLJIT_CONFIG_RISCV_ICOND != 0 */
+
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+#define RISCV_CHECK_COMPRESSED_JUMP(jump, diff, unit) \
+ (!((jump)->flags & IS_CALL) && (diff) >= (JUMP16_MIN / SSIZE_OF(unit)) && (diff) <= (JUMP16_MAX / SSIZE_OF(unit)))
+#else /* !SLJIT_CONFIG_RISCV_64 */
+#define RISCV_CHECK_COMPRESSED_JUMP(jump, diff, unit) \
+ ((diff) >= (JUMP16_MIN / SSIZE_OF(unit)) && (diff) <= (JUMP16_MAX / SSIZE_OF(unit)))
+#endif /* SLJIT_CONFIG_RISCV_64 */
+
SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void)
{
+ /* The arch string is not entirely correct since 'g' contains 'a'. */
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- return "RISC-V-32" SLJIT_CPUINFO;
+ return "RISC-V-32 (rv32g" RISCV_ATOMIC_INFO RISCV_COMPRESSED_INFO RISCV_VECTOR_INFO RISCV_BITMANIP_A_INFO RISCV_BITMANIP_B_INFO RISCV_ICOND_INFO ")" SLJIT_CPUINFO;
#else /* !SLJIT_CONFIG_RISCV_32 */
- return "RISC-V-64" SLJIT_CPUINFO;
+ return "RISC-V-64 (rv64g" RISCV_ATOMIC_INFO RISCV_COMPRESSED_INFO RISCV_VECTOR_INFO RISCV_BITMANIP_A_INFO RISCV_BITMANIP_B_INFO RISCV_ICOND_INFO ")" SLJIT_CPUINFO;
#endif /* SLJIT_CONFIG_RISCV_32 */
}
-/* Length of an instruction word
- Both for riscv-32 and riscv-64 */
+/* Most instructions are 32 bit long on RISCV.
+ Code is processed as 16 bit units. */
typedef sljit_u32 sljit_ins;
#define TMP_REG1 (SLJIT_NUMBER_OF_REGISTERS + 2)
@@ -66,7 +197,7 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
};
/* --------------------------------------------------------------------- */
-/* Instrucion forms */
+/* Instruction forms */
/* --------------------------------------------------------------------- */
#define RD(rd) ((sljit_ins)reg_map[rd] << 7)
@@ -80,9 +211,28 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
#define VRS2(rs2) ((sljit_ins)vreg_map[rs2] << 20)
#define IMM_I(imm) ((sljit_ins)(imm) << 20)
#define IMM_S(imm) ((((sljit_ins)(imm) & 0xfe0) << 20) | (((sljit_ins)(imm) & 0x1f) << 7))
+#define C_RD(rd) ((sljit_u16)((sljit_u16)reg_map[rd] << 7))
+#define C_RS2(rd) ((sljit_u16)((sljit_u16)reg_map[rd] << 2))
+#define C_FRD(rd) ((sljit_u16)((sljit_u16)freg_map[rd] << 7))
+#define C_FRS2(rd) ((sljit_u16)((sljit_u16)freg_map[rd] << 2))
+#define C_RS1_R3(rs1) ((sljit_u16)((sljit_u16)(reg_map[rs1] & 0x7) << 7))
+#define C_RS2_R3(rs2) ((sljit_u16)((sljit_u16)(reg_map[rs2] & 0x7) << 2))
+#define C_FRS2_R3(rs2) ((sljit_u16)((sljit_u16)(freg_map[rs2] & 0x7) << 2))
+#define C_IS_R3(r) ((reg_map[r] & 0x18) == 0x08)
+#define C_IS_FR3(r) ((freg_map[r] & 0x18) == 0x08)
+#define C_IMM_I(imm) ((sljit_u16)((((imm) & 0x1f) << 2) | (((imm) & 0x20) << 7)))
+#define C_LD32_SP(imm) ((sljit_u16)((((imm) & 0x1c) << 2) | (((imm) & 0x20) << 7) | (((imm) & 0xc0) >> 4)))
+#define C_ST32_SP(imm) ((sljit_u16)((((imm) & 0x3c) << 7) | (((imm) & 0xc0) << 1)))
+#define C_LD64_SP(imm) ((sljit_u16)((((imm) & 0x18) << 2) | (((imm) & 0x20) << 7) | (((imm) & 0x1c0) >> 4)))
+#define C_ST64_SP(imm) ((sljit_u16)((((imm) & 0x38) << 7) | (((imm) & 0x1c0) << 1)))
+#define C_MEM32(imm) ((sljit_u16)((((imm) & 0x4) << 4) | (((imm) & 0x38) << 7) | (((imm) & 0x40) >> 1)))
+#define C_MEM64(imm) ((sljit_u16)((((imm) & 0x38) << 7) | (((imm) & 0xc0) >> 1)))
+#define C_BRN16(imm) ((sljit_u16)((((imm) & 0x6) << 2) | (((imm) & 0x18) << 7) | (((imm) & 0x20) >> 3) | (((imm) & 0xc0) >> 1) | (((imm) & 0x100) << 4)))
+#define C_JMP16(imm) ((sljit_u16)((((imm) & 0xb40) << 1) | (((imm) & 0xe) << 2) | (((imm) & 0x10) << 7) | (((imm) & 0x20) >> 3) | (((imm) & 0x80) >> 1) | (((imm) & 0x400) >> 2)))
/* Represents funct(i) parts of the instructions. */
#define OPC(o) ((sljit_ins)(o))
+#define C_OPC(o1, o2) ((sljit_u16)((o1) | ((o2) << 13)))
#define F3(f) ((sljit_ins)(f) << 12)
#define F12(f) ((sljit_ins)(f) << 20)
#define F7(f) ((sljit_ins)(f) << 25)
@@ -107,10 +257,50 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
#define BGE (F3(0x5) | OPC(0x63))
#define BLTU (F3(0x6) | OPC(0x63))
#define BGEU (F3(0x7) | OPC(0x63))
-#if defined __riscv_zbb
+/* C_*: compressed */
+#define C_ADD (C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12))
+#define C_ADDI (C_OPC(0x1, 0x0))
+#define C_ADDIW (C_OPC(0x1, 0x1))
+#define C_ADDW (C_OPC(0x1, 0x4) | (sljit_u16)(7 << 10) | (sljit_u16)(1 << 5))
+#define C_ADDI16SP (C_OPC(0x1, 0x3) | (sljit_u16)(2 << 7))
+#define C_AND (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(3 << 5))
+#define C_ANDI (C_OPC(0x1, 0x4) | (sljit_u16)(2 << 10))
+#define C_BEQZ (C_OPC(0x1, 0x6))
+#define C_BNEZ (C_OPC(0x1, 0x7))
+#define C_EBREAK (C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12))
+#define C_FLDSP (C_OPC(0x2, 0x1))
+#define C_FLWSP (C_OPC(0x2, 0x3))
+#define C_FSD (C_OPC(0x0, 0x5))
+#define C_FSDSP (C_OPC(0x2, 0x5))
+#define C_FSW (C_OPC(0x0, 0x7))
+#define C_FSWSP (C_OPC(0x2, 0x7))
+#define C_J (C_OPC(0x1, 0x5))
+#define C_JR (C_OPC(0x2, 0x4))
+#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
+#define C_JAL (C_OPC(0x1, 0x1))
+#endif
+#define C_JALR (C_OPC(0x2, 0x4) | (sljit_u16)(1 << 12))
+#define C_LI (C_OPC(0x1, 0x2))
+#define C_LUI (C_OPC(0x1, 0x3))
+#define C_LDSP (C_OPC(0x2, 0x3))
+#define C_LWSP (C_OPC(0x2, 0x2))
+#define C_MV (C_OPC(0x2, 0x4))
+#define C_NOP (C_OPC(0x1, 0x0))
+#define C_SD (C_OPC(0x0, 0x7))
+#define C_SDSP (C_OPC(0x2, 0x7))
+#define C_SLLI (C_OPC(0x2, 0x0))
+#define C_OR (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(2 << 5))
+#define C_SRAI (C_OPC(0x1, 0x4) | (sljit_u16)(1 << 10))
+#define C_SRLI (C_OPC(0x1, 0x4) | (sljit_u16)(0 << 10))
+#define C_SUB (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(0 << 5))
+#define C_SW (C_OPC(0x0, 0x6))
+#define C_SWSP (C_OPC(0x2, 0x6))
+#define C_XOR (C_OPC(0x1, 0x4) | (sljit_u16)(3 << 10) | (sljit_u16)(1 << 5))
+/* CLZ / CTZ: zbb */
#define CLZ (F7(0x30) | F3(0x1) | OPC(0x13))
#define CTZ (F7(0x30) | F12(0x1) | F3(0x1) | OPC(0x13))
-#endif /* __riscv_zbb */
+#define CZERO_EQZ (F7(0x7) | F3(0x5) | OPC(0x33))
+#define CZERO_NEZ (F7(0x7) | F3(0x7) | OPC(0x33))
#define DIV (F7(0x1) | F3(0x4) | OPC(0x33))
#define DIVU (F7(0x1) | F3(0x5) | OPC(0x33))
#define EBREAK (F12(0x1) | F3(0x0) | OPC(0x73))
@@ -140,35 +330,39 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
#define LD (F3(0x3) | OPC(0x3))
#define LUI (OPC(0x37))
#define LW (F3(0x2) | OPC(0x3))
+/* LR: atomic */
#define LR (F7(0x8) | OPC(0x2f))
+#define MAX (F7(0x5) | F3(0x6) | OPC(0x33))
+#define MAXU (F7(0x5) | F3(0x7) | OPC(0x33))
+#define MIN (F7(0x5) | F3(0x4) | OPC(0x33))
+#define MINU (F7(0x5) | F3(0x5) | OPC(0x33))
#define MUL (F7(0x1) | F3(0x0) | OPC(0x33))
#define MULH (F7(0x1) | F3(0x1) | OPC(0x33))
#define MULHU (F7(0x1) | F3(0x3) | OPC(0x33))
+#define NOP ADDI
#define OR (F7(0x0) | F3(0x6) | OPC(0x33))
#define ORI (F3(0x6) | OPC(0x13))
#define REM (F7(0x1) | F3(0x6) | OPC(0x33))
#define REMU (F7(0x1) | F3(0x7) | OPC(0x33))
-#if defined __riscv_zbb
-#if defined SLJIT_CONFIG_RISCV_32
+/* REV8 / ROL / ROR / RORI: zbb */
+#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
#define REV8 (F12(0x698) | F3(0x5) | OPC(0x13))
-#elif defined SLJIT_CONFIG_RISCV_64
+#elif (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
#define REV8 (F12(0x6b8) | F3(0x5) | OPC(0x13))
#endif /* SLJIT_CONFIG_RISCV_32 */
#define ROL (F7(0x30) | F3(0x1) | OPC(0x33))
#define ROR (F7(0x30) | F3(0x5) | OPC(0x33))
#define RORI (F7(0x30) | F3(0x5) | OPC(0x13))
-#endif /* __riscv_zbb */
+/* SC: atomic */
#define SC (F7(0xc) | OPC(0x2f))
#define SD (F3(0x3) | OPC(0x23))
-#if defined __riscv_zbb
+/* SEXTB / SEXTH: zbb */
#define SEXTB (F7(0x30) | F12(0x4) | F3(0x1) | OPC(0x13))
#define SEXTH (F7(0x30) | F12(0x5) | F3(0x1) | OPC(0x13))
-#endif /* __riscv_zbb */
-#if defined __riscv_zba
+/* SH1ADD / SH2ADD / SH3ADD: zba */
#define SH1ADD (F7(0x10) | F3(0x2) | OPC(0x33))
#define SH2ADD (F7(0x10) | F3(0x4) | OPC(0x33))
#define SH3ADD (F7(0x10) | F3(0x6) | OPC(0x33))
-#endif /* __riscv_zba */
#define SLL (F7(0x0) | F3(0x1) | OPC(0x33))
#define SLLI (F3(0x1) | OPC(0x13))
#define SLT (F7(0x0) | F3(0x2) | OPC(0x33))
@@ -181,6 +375,7 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
#define SRAI (F7(0x20) | F3(0x5) | OPC(0x13))
#define SUB (F7(0x20) | F3(0x0) | OPC(0x33))
#define SW (F3(0x2) | OPC(0x23))
+/* V*: vector */
#define VAND_VV (F7(0x13) | OPIVV)
#define VFMV_FS (F7(0x21) | OPFVV)
#define VFMV_SF (F7(0x21) | OPFVF)
@@ -194,6 +389,7 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
#define VMV_VX (F7(0x2f) | OPIVX)
#define VMV_XS (F7(0x21) | OPMVV)
#define VOR_VV (F7(0x15) | OPIVV)
+#define VSETVLI (F7(0x0) | F3(0x7) | OPC(0x57))
#define VSETIVLI (F7(0x60) | F3(0x7) | OPC(0x57))
#define VS (F7(0x1) | OPC(0x27))
#define VSLIDEDOWN_VX (F7(0x1f) | OPIVX)
@@ -208,20 +404,25 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
#define VZEXT_VF8 (F7(0x25) | (0x2 << 15) | OPMVV)
#define XOR (F7(0x0) | F3(0x4) | OPC(0x33))
#define XORI (F3(0x4) | OPC(0x13))
-#if defined __riscv_zbb
-#if defined SLJIT_CONFIG_RISCV_32
+/* ZEXTH: zbb */
+#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
#define ZEXTH (F7(0x4) | F3(0x4) | OPC(0x33))
-#elif defined SLJIT_CONFIG_RISCV_64
+#else /* SLJIT_CONFIG_RISCV_64 */
#define ZEXTH (F7(0x4) | F3(0x4) | OPC(0x3B))
#endif /* SLJIT_CONFIG_RISCV_32 */
-#endif /* __riscv_zbb */
#define SIMM_MAX (0x7ff)
#define SIMM_MIN (-0x800)
+#define SIMM16_MAX (0x1f)
+#define SIMM16_MIN (-0x20)
#define BRANCH_MAX (0xfff)
#define BRANCH_MIN (-0x1000)
+#define BRANCH16_MAX (0xff)
+#define BRANCH16_MIN (-0x100)
#define JUMP_MAX (0xfffff)
#define JUMP_MIN (-0x100000)
+#define JUMP16_MAX SIMM_MAX
+#define JUMP16_MIN SIMM_MIN
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
#define S32_MAX (0x7ffff7ffl)
@@ -230,9 +431,30 @@ static const sljit_u8 vreg_map[SLJIT_NUMBER_OF_VECTOR_REGISTERS + 3] = {
#define S52_MAX (0x7ffffffffffffl)
#endif /* SLJIT_CONFIG_RISCV_64 */
+#define C_ADDI_W(word) (C_ADDI | (sljit_u16)((word) << 10))
+#define C_SUB_W(word) (C_SUB | (sljit_u16)((word) << 9))
+
+#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
+#define BRANCH_LENGTH ((sljit_ins)(3 * sizeof(sljit_ins)) << 7)
+#define BRANCH16_LENGTH C_BRN16(5 * sizeof(sljit_u16))
+#else /* !SLJIT_CONFIG_RISCV_32 */
+#define BRANCH_LENGTH ((sljit_ins)(7 * sizeof(sljit_ins)) << 7)
+#define BRANCH16_LENGTH C_BRN16(13 * sizeof(sljit_u16))
+#endif /* SLJIT_CONFIG_RISCV_32 */
+
static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins)
{
- sljit_ins *ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_ins));
+ FAIL_IF(!ptr);
+ ptr[0] = (sljit_u16)ins;
+ ptr[1] = (sljit_u16)(ins >> 16);
+ compiler->size += 2;
+ return SLJIT_SUCCESS;
+}
+
+static sljit_s32 push_inst16(struct sljit_compiler *compiler, sljit_u16 ins)
+{
+ sljit_u16 *ptr = (sljit_u16*)ensure_buf(compiler, sizeof(sljit_u16));
FAIL_IF(!ptr);
*ptr = ins;
compiler->size++;
@@ -244,12 +466,16 @@ static sljit_s32 push_imm_s_inst(struct sljit_compiler *compiler, sljit_ins ins,
return push_inst(compiler, ins | IMM_S(imm));
}
-static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+static SLJIT_INLINE sljit_u16* detect_jump_type(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
{
- sljit_sw diff;
+ sljit_sw diff, cond_diff;
sljit_uw target_addr;
sljit_uw jump_addr = (sljit_uw)code_ptr;
sljit_uw orig_addr = jump->addr;
+ sljit_ins ins;
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ sljit_s32 jalr_offset = JUMP_MAX_SIZE - 1;
+#endif /* SLJIT_CONFIG_RISCV_64 */
SLJIT_UNUSED_ARG(executable_offset);
jump->addr = jump_addr;
@@ -269,90 +495,131 @@ static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_i
diff = (sljit_sw)target_addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);
if (jump->flags & IS_COND) {
- diff += SSIZE_OF(ins);
+ cond_diff = diff + SSIZE_OF(ins);
+
+ if (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16))) {
+ SLJIT_ASSERT((code_ptr[-1] & 0xe003) == C_BEQZ || (code_ptr[-1] & 0xe003) == C_BNEZ);
+
+ cond_diff = diff + SSIZE_OF(u16);
+
+ if (diff >= BRANCH16_MIN && diff <= BRANCH16_MAX) {
+ code_ptr--;
+ code_ptr[0] = (sljit_u16)((code_ptr[0] & 0xe383) ^ 0x2000);
+ jump->flags |= PATCH_B | PATCH_16;
+ jump->addr = (sljit_uw)code_ptr;
+ return code_ptr;
+ }
+ }
+
+ if (cond_diff >= BRANCH_MIN && cond_diff <= BRANCH_MAX) {
+ if (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16))) {
+ /* Converting 16 bit branch to 32 bit branch. */
+ code_ptr--;
+ code_ptr[1] = (sljit_u16)(((code_ptr[0] & 0x300) >> 8) | 0x4);
+ code_ptr[0] = (sljit_u16)((BNE ^ ((code_ptr[0] & 0x2000) >> 1)) | ((code_ptr[0] & 0x80) << 8));
+ } else {
+ code_ptr -= 2;
+ code_ptr[0] = (sljit_u16)((code_ptr[0] & 0xf07f) ^ 0x1000);
+ code_ptr[1] = (sljit_u16)(code_ptr[1] & 0x1ff);
+ }
- if (diff >= BRANCH_MIN && diff <= BRANCH_MAX) {
- code_ptr--;
- code_ptr[0] = (code_ptr[0] & 0x1fff07f) ^ 0x1000;
jump->flags |= PATCH_B;
jump->addr = (sljit_uw)code_ptr;
- return code_ptr;
+ return code_ptr + 1;
}
+ }
- diff -= SSIZE_OF(ins);
+ if (RISCV_HAS_COMPRESSED(200) && RISCV_CHECK_COMPRESSED_JUMP(jump, diff, u8)) {
+ /* A conditional instruction has larger max offset
+ than a 16 bit jump instruction. */
+ SLJIT_ASSERT(!(jump->flags & IS_COND));
+ jump->flags |= PATCH_J | PATCH_16;
+ return code_ptr;
}
if (diff >= JUMP_MIN && diff <= JUMP_MAX) {
if (jump->flags & IS_COND) {
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- code_ptr[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7;
-#else /* !SLJIT_CONFIG_RISCV_32 */
- code_ptr[-1] -= (sljit_ins)(5 * sizeof(sljit_ins)) << 7;
-#endif /* SLJIT_CONFIG_RISCV_32 */
+ if (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))
+ code_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(3 * sizeof(sljit_u16)));
+ else
+ code_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (2 * sizeof(sljit_ins) << 7));
}
jump->flags |= PATCH_J;
- return code_ptr;
+ return code_ptr + 1;
}
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
if (diff >= S32_MIN && diff <= S32_MAX) {
- if (jump->flags & IS_COND)
- code_ptr[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7;
+ if (jump->flags & IS_COND) {
+ if (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))
+ code_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(5 * sizeof(sljit_u16)));
+ else
+ code_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (3 * sizeof(sljit_ins) << 7));
+ }
jump->flags |= PATCH_REL32;
- code_ptr[1] = code_ptr[0];
- return code_ptr + 1;
- }
-
- if (target_addr <= (sljit_uw)S32_MAX) {
- if (jump->flags & IS_COND)
- code_ptr[-1] -= (sljit_ins)(4 * sizeof(sljit_ins)) << 7;
+ jalr_offset = 3;
+ } else if (target_addr <= (sljit_uw)S32_MAX) {
+ if (jump->flags & IS_COND) {
+ if (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))
+ code_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(5 * sizeof(sljit_u16)));
+ else
+ code_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (3 * sizeof(sljit_ins) << 7));
+ }
jump->flags |= PATCH_ABS32;
- code_ptr[1] = code_ptr[0];
- return code_ptr + 1;
- }
-
- if (target_addr <= S44_MAX) {
- if (jump->flags & IS_COND)
- code_ptr[-1] -= (sljit_ins)(2 * sizeof(sljit_ins)) << 7;
+ jalr_offset = 3;
+ } else if (target_addr <= S44_MAX) {
+ if (jump->flags & IS_COND) {
+ if (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))
+ code_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(9 * sizeof(sljit_u16)));
+ else
+ code_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (5 * sizeof(sljit_ins) << 7));
+ }
jump->flags |= PATCH_ABS44;
- code_ptr[3] = code_ptr[0];
- return code_ptr + 3;
- }
-
- if (target_addr <= S52_MAX) {
- if (jump->flags & IS_COND)
- code_ptr[-1] -= (sljit_ins)(1 * sizeof(sljit_ins)) << 7;
+ jalr_offset = 7;
+ } else if (target_addr <= S52_MAX) {
+ if (jump->flags & IS_COND) {
+ if (RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16)))
+ code_ptr[-1] ^= (sljit_u16)(BRANCH16_LENGTH ^ C_BRN16(11 * sizeof(sljit_u16)));
+ else
+ code_ptr[-2] ^= (sljit_u16)(BRANCH_LENGTH ^ (6 * sizeof(sljit_ins) << 7));
+ }
jump->flags |= PATCH_ABS52;
- code_ptr[4] = code_ptr[0];
- return code_ptr + 4;
+ jalr_offset = 9;
}
#endif /* SLJIT_CONFIG_RISCV_64 */
exit:
+ ins = JALR | RS1(TMP_REG1) | IMM_I(0);
+ if (jump->flags & IS_CALL)
+ ins |= RD(RETURN_ADDR_REG);
+
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- code_ptr[1] = code_ptr[0];
- return code_ptr + 1;
+ code_ptr[2] = (sljit_u16)ins;
+ code_ptr[3] = (sljit_u16)(ins >> 16);
+ return code_ptr + 3;
#else /* !SLJIT_CONFIG_RISCV_32 */
- code_ptr[5] = code_ptr[0];
- return code_ptr + 5;
+ code_ptr += jalr_offset;
+ code_ptr[-1] = (sljit_u16)ins;
+ code_ptr[0] = (sljit_u16)(ins >> 16);
+ return code_ptr;
#endif /* SLJIT_CONFIG_RISCV_32 */
}
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
-static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset)
+static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_u16 *code_ptr, sljit_u16 *code, sljit_sw executable_offset)
{
sljit_uw addr;
sljit_uw jump_addr = (sljit_uw)code_ptr;
sljit_sw diff;
SLJIT_UNUSED_ARG(executable_offset);
- SLJIT_ASSERT(jump->flags < ((sljit_uw)6 << JUMP_SIZE_SHIFT));
+ SLJIT_ASSERT(jump->flags < (JUMP_MAX_SIZE << JUMP_SIZE_SHIFT));
if (jump->flags & JUMP_ADDR)
addr = jump->u.target;
else {
@@ -365,31 +632,31 @@ static SLJIT_INLINE sljit_sw mov_addr_get_length(struct sljit_jump *jump, sljit_
diff = (sljit_sw)addr - (sljit_sw)SLJIT_ADD_EXEC_OFFSET(jump_addr, executable_offset);
if (diff >= S32_MIN && diff <= S32_MAX) {
- SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+ SLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));
jump->flags |= PATCH_REL32;
- return 1;
+ return 3;
}
if (addr <= S32_MAX) {
- SLJIT_ASSERT(jump->flags >= ((sljit_uw)1 << JUMP_SIZE_SHIFT));
+ SLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));
jump->flags |= PATCH_ABS32;
- return 1;
+ return 3;
}
if (addr <= S44_MAX) {
- SLJIT_ASSERT(jump->flags >= ((sljit_uw)3 << JUMP_SIZE_SHIFT));
+ SLJIT_ASSERT(jump->flags >= ((sljit_uw)7 << JUMP_SIZE_SHIFT));
jump->flags |= PATCH_ABS44;
- return 3;
+ return 7;
}
if (addr <= S52_MAX) {
- SLJIT_ASSERT(jump->flags >= ((sljit_uw)4 << JUMP_SIZE_SHIFT));
+ SLJIT_ASSERT(jump->flags >= ((sljit_uw)9 << JUMP_SIZE_SHIFT));
jump->flags |= PATCH_ABS52;
- return 4;
+ return 9;
}
- SLJIT_ASSERT(jump->flags >= ((sljit_uw)5 << JUMP_SIZE_SHIFT));
- return 5;
+ SLJIT_ASSERT(jump->flags >= ((sljit_uw)11 << JUMP_SIZE_SHIFT));
+ return 11;
}
#endif /* SLJIT_CONFIG_RISCV_64 */
@@ -398,8 +665,9 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec
{
sljit_uw flags = jump->flags;
sljit_uw addr = (flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
- sljit_ins *ins = (sljit_ins*)jump->addr;
- sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *ins : TMP_REG1;
+ sljit_ins ins;
+ sljit_u16 *buf = (sljit_u16 *)jump->addr;
+ sljit_u32 reg = (flags & JUMP_MOV_ADDR) ? *buf : TMP_REG1;
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
sljit_sw high;
#endif /* SLJIT_CONFIG_RISCV_64 */
@@ -407,20 +675,26 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
if (flags & PATCH_REL32) {
- addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(ins, executable_offset);
+ addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf, executable_offset);
SLJIT_ASSERT((sljit_sw)addr >= S32_MIN && (sljit_sw)addr <= S32_MAX);
if ((addr & 0x800) != 0)
addr += 0x1000;
- ins[0] = AUIPC | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+ ins = AUIPC | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+ buf[0] = (sljit_u16)ins;
+ buf[1] = (sljit_u16)(ins >> 16);
if (!(flags & JUMP_MOV_ADDR)) {
- SLJIT_ASSERT((ins[1] & 0x707f) == JALR);
- ins[1] = (ins[1] & 0xfffff) | IMM_I(addr);
+ ins = JALR | RS1(reg) | IMM_I(addr);
+ if (jump->flags & IS_CALL)
+ ins |= RD(RETURN_ADDR_REG);
} else
- ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
+ ins = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
+
+ buf[2] = (sljit_u16)ins;
+ buf[3] = (sljit_u16)(ins >> 16);
return;
}
#endif /* SLJIT_CONFIG_RISCV_64 */
@@ -429,30 +703,44 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec
addr += 0x1000;
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- ins[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+ ins = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+ buf[0] = (sljit_u16)ins;
+ buf[1] = (sljit_u16)(ins >> 16);
#else /* !SLJIT_CONFIG_RISCV_32 */
if (flags & PATCH_ABS32) {
SLJIT_ASSERT(addr <= S32_MAX);
- ins[0] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+ ins = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+ buf[0] = (sljit_u16)ins;
+ buf[1] = (sljit_u16)(ins >> 16);
} else if (flags & PATCH_ABS44) {
high = (sljit_sw)addr >> 12;
SLJIT_ASSERT((sljit_uw)high <= 0x7fffffff);
if (high > S32_MAX) {
SLJIT_ASSERT((high & 0x800) != 0);
- ins[0] = LUI | RD(reg) | (sljit_ins)0x80000000u;
- ins[1] = XORI | RD(reg) | RS1(reg) | IMM_I(high);
+ ins = LUI | RD(reg) | (sljit_ins)0x80000000u;
+ buf[0] = (sljit_u16)ins;
+ buf[1] = (sljit_u16)(ins >> 16);
+ ins = XORI | RD(reg) | RS1(reg) | IMM_I(high);
+ buf[2] = (sljit_u16)ins;
+ buf[3] = (sljit_u16)(ins >> 16);
} else {
if ((high & 0x800) != 0)
high += 0x1000;
- ins[0] = LUI | RD(reg) | (sljit_ins)(high & ~0xfff);
- ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(high);
+ ins = LUI | RD(reg) | (sljit_ins)(high & ~0xfff);
+ buf[0] = (sljit_u16)ins;
+ buf[1] = (sljit_u16)(ins >> 16);
+ ins = ADDI | RD(reg) | RS1(reg) | IMM_I(high);
+ buf[2] = (sljit_u16)ins;
+ buf[3] = (sljit_u16)(ins >> 16);
}
- ins[2] = SLLI | RD(reg) | RS1(reg) | IMM_I(12);
- ins += 2;
+ ins = SLLI | RD(reg) | RS1(reg) | IMM_I(12);
+ buf[4] = (sljit_u16)ins;
+ buf[5] = (sljit_u16)(ins >> 16);
+ buf += 4;
} else {
high = (sljit_sw)addr >> 32;
@@ -461,27 +749,49 @@ static SLJIT_INLINE void load_addr_to_reg(struct sljit_jump *jump, sljit_sw exec
if (flags & PATCH_ABS52) {
SLJIT_ASSERT(addr <= S52_MAX);
- ins[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12);
+ ins = LUI | RD(TMP_REG3) | (sljit_ins)(high << 12);
+ buf[0] = (sljit_u16)ins;
+ buf[1] = (sljit_u16)(ins >> 16);
} else {
if ((high & 0x800) != 0)
high += 0x1000;
- ins[0] = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff);
- ins[1] = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high);
- ins++;
+ ins = LUI | RD(TMP_REG3) | (sljit_ins)(high & ~0xfff);
+ buf[0] = (sljit_u16)ins;
+ buf[1] = (sljit_u16)(ins >> 16);
+ ins = ADDI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I(high);
+ buf[2] = (sljit_u16)ins;
+ buf[3] = (sljit_u16)(ins >> 16);
+ buf += 2;
}
- ins[1] = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
- ins[2] = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32);
- ins[3] = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3);
- ins += 3;
+ ins = LUI | RD(reg) | (sljit_ins)((sljit_sw)addr & ~0xfff);
+ buf[2] = (sljit_u16)ins;
+ buf[3] = (sljit_u16)(ins >> 16);
+ ins = SLLI | RD(TMP_REG3) | RS1(TMP_REG3) | IMM_I((flags & PATCH_ABS52) ? 20 : 32);
+ buf[4] = (sljit_u16)ins;
+ buf[5] = (sljit_u16)(ins >> 16);
+ ins = XOR | RD(reg) | RS1(reg) | RS2(TMP_REG3);
+ buf[6] = (sljit_u16)ins;
+ buf[7] = (sljit_u16)(ins >> 16);
+ buf += 6;
}
#endif /* !SLJIT_CONFIG_RISCV_32 */
if (!(flags & JUMP_MOV_ADDR)) {
- SLJIT_ASSERT((ins[1] & 0x707f) == JALR);
- ins[1] = (ins[1] & 0xfffff) | IMM_I(addr);
+ ins = JALR | RS1(reg) | IMM_I(addr);
+ if (jump->flags & IS_CALL)
+ ins |= RD(RETURN_ADDR_REG);
} else
- ins[1] = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
+ ins = ADDI | RD(reg) | RS1(reg) | IMM_I(addr);
+
+ buf[2] = (sljit_u16)ins;
+ buf[3] = (sljit_u16)(ins >> 16);
+}
+
+static SLJIT_INLINE sljit_u16 *process_extended_label(sljit_u16 *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_u16*)((sljit_uw)code_ptr & ~(ext_label->data));
}
static void reduce_code_size(struct sljit_compiler *compiler)
@@ -492,7 +802,7 @@ static void reduce_code_size(struct sljit_compiler *compiler)
SLJIT_NEXT_DEFINE_TYPES;
sljit_uw total_size;
sljit_uw size_reduce = 0;
- sljit_sw diff;
+ sljit_sw diff, cond_size, cond_diff;
label = compiler->labels;
jump = compiler->jumps;
@@ -530,11 +840,11 @@ static void reduce_code_size(struct sljit_compiler *compiler)
if (jump->flags & JUMP_ADDR) {
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
if (jump->u.target <= S32_MAX)
- total_size = 2;
- else if (jump->u.target <= S44_MAX)
total_size = 4;
+ else if (jump->u.target <= S44_MAX)
+ total_size = 8;
else if (jump->u.target <= S52_MAX)
- total_size = 5;
+ total_size = 10;
#endif /* SLJIT_CONFIG_RISCV_64 */
} else {
/* Unit size: instruction. */
@@ -544,13 +854,20 @@ static void reduce_code_size(struct sljit_compiler *compiler)
diff -= (sljit_sw)size_reduce;
}
- if ((jump->flags & IS_COND) && (diff + 1) <= (BRANCH_MAX / SSIZE_OF(ins)) && (diff + 1) >= (BRANCH_MIN / SSIZE_OF(ins)))
+ cond_size = RISCV_COMPRESSED_CHECK((jump->flags & IS_COND16) != 0);
+ cond_diff = diff + 2 - cond_size;
+
+ if (RISCV_COMPRESSED_CHECK(cond_size) && diff >= (BRANCH16_MIN / SSIZE_OF(u16)) && diff <= (BRANCH16_MAX / SSIZE_OF(u16)))
total_size = 0;
- else if (diff >= (JUMP_MIN / SSIZE_OF(ins)) && diff <= (JUMP_MAX / SSIZE_OF(ins)))
+ else if ((jump->flags & IS_COND) && cond_diff <= (BRANCH_MAX / SSIZE_OF(u16)) && cond_diff >= (BRANCH_MIN / SSIZE_OF(u16)))
+ total_size = (sljit_uw)cond_size;
+ else if (RISCV_HAS_COMPRESSED(200) && RISCV_CHECK_COMPRESSED_JUMP(jump, diff, u16))
total_size = 1;
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- else if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))
+ else if (diff >= (JUMP_MIN / SSIZE_OF(u16)) && diff <= (JUMP_MAX / SSIZE_OF(u16)))
total_size = 2;
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ else if (diff >= (S32_MIN / SSIZE_OF(u16)) && diff <= (S32_MAX / SSIZE_OF(u16)))
+ total_size = 4;
#endif /* SLJIT_CONFIG_RISCV_64 */
}
}
@@ -559,26 +876,26 @@ static void reduce_code_size(struct sljit_compiler *compiler)
jump->flags |= total_size << JUMP_SIZE_SHIFT;
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
} else {
- total_size = 5;
+ total_size = 11;
if (!(jump->flags & JUMP_ADDR)) {
- /* Real size minus 1. Unit size: instruction. */
+ /* Real size minus 1. Unit size: 16 bit. */
diff = (sljit_sw)jump->u.label->size - (sljit_sw)jump->addr;
if (jump->u.label->size > jump->addr) {
SLJIT_ASSERT(jump->u.label->size - size_reduce >= jump->addr);
diff -= (sljit_sw)size_reduce;
}
- if (diff >= (S32_MIN / SSIZE_OF(ins)) && diff <= (S32_MAX / SSIZE_OF(ins)))
- total_size = 1;
+ if (diff >= (S32_MIN / SSIZE_OF(u16)) && diff <= (S32_MAX / SSIZE_OF(u16)))
+ total_size = 3;
} else if (jump->u.target < S32_MAX)
- total_size = 1;
- else if (jump->u.target < S44_MAX)
total_size = 3;
+ else if (jump->u.target < S44_MAX)
+ total_size = 7;
else if (jump->u.target <= S52_MAX)
- total_size = 4;
+ total_size = 9;
- size_reduce += 5 - total_size;
+ size_reduce += 11 - total_size;
jump->flags |= total_size << JUMP_SIZE_SHIFT;
#endif /* !SLJIT_CONFIG_RISCV_64 */
}
@@ -593,32 +910,33 @@ static void reduce_code_size(struct sljit_compiler *compiler)
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
{
struct sljit_memory_fragment *buf;
- sljit_ins *code;
- sljit_ins *code_ptr;
- sljit_ins *buf_ptr;
- sljit_ins *buf_end;
- sljit_uw word_count;
+ sljit_u16 *code;
+ sljit_u16 *code_ptr;
+ sljit_u16 *buf_ptr;
+ sljit_u16 *buf_end;
+ sljit_uw half_count;
SLJIT_NEXT_DEFINE_TYPES;
sljit_sw executable_offset;
sljit_uw addr;
+ sljit_ins ins;
struct sljit_label *label;
struct sljit_jump *jump;
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reduce_code_size(compiler);
- code = (sljit_ins*)allocate_executable_memory(compiler->size * sizeof(sljit_ins), options, exec_allocator_data, &executable_offset);
+ code = (sljit_u16 *)allocate_executable_memory(compiler->size * sizeof(sljit_u16), options, exec_allocator_data, &executable_offset);
PTR_FAIL_WITH_EXEC_IF(code);
reverse_buf(compiler);
buf = compiler->buf;
code_ptr = code;
- word_count = 0;
+ half_count = 0;
label = compiler->labels;
jump = compiler->jumps;
const_ = compiler->consts;
@@ -626,17 +944,22 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_GET_NEXT_MIN();
do {
- buf_ptr = (sljit_ins*)buf->memory;
- buf_end = buf_ptr + (buf->used_size >> 2);
+ buf_ptr = (sljit_u16*)buf->memory;
+ buf_end = buf_ptr + (buf->used_size >> 1);
do {
*code_ptr = *buf_ptr++;
- if (next_min_addr == word_count) {
- SLJIT_ASSERT(!label || label->size >= word_count);
- SLJIT_ASSERT(!jump || jump->addr >= word_count);
- SLJIT_ASSERT(!const_ || const_->addr >= word_count);
+ if (next_min_addr == half_count) {
+ SLJIT_ASSERT(!label || label->size >= half_count);
+ SLJIT_ASSERT(!jump || jump->addr >= half_count);
+ SLJIT_ASSERT(!const_ || const_->addr >= half_count);
/* These structures are ordered by their address. */
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+ *code_ptr = buf_ptr[-1];
+ }
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -645,16 +968,16 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
if (next_min_addr == next_jump_addr) {
if (!(jump->flags & JUMP_MOV_ADDR)) {
- word_count = word_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);
+ half_count = half_count - 1 + (jump->flags >> JUMP_SIZE_SHIFT);
code_ptr = detect_jump_type(jump, code_ptr, code, executable_offset);
SLJIT_ASSERT((jump->flags & PATCH_B) || ((sljit_uw)code_ptr - jump->addr < (jump->flags >> JUMP_SIZE_SHIFT) * sizeof(sljit_ins)));
} else {
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- word_count += 1;
+ half_count += 3;
jump->addr = (sljit_uw)code_ptr;
- code_ptr += 1;
+ code_ptr += 3;
#else /* !SLJIT_CONFIG_RISCV_32 */
- word_count += jump->flags >> JUMP_SIZE_SHIFT;
+ half_count += jump->flags >> JUMP_SIZE_SHIFT;
addr = (sljit_uw)code_ptr;
code_ptr += mov_addr_get_length(jump, code_ptr, code, executable_offset);
jump->addr = addr;
@@ -671,13 +994,16 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_GET_NEXT_MIN();
}
code_ptr++;
- word_count++;
+ half_count++;
} while (buf_ptr < buf_end);
buf = buf->next;
} while (buf);
- if (label && label->size == word_count) {
+ if (label && label->size == half_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)code_ptr;
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -697,19 +1023,41 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
}
addr = (jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr;
- buf_ptr = (sljit_ins *)jump->addr;
+ buf_ptr = (sljit_u16 *)jump->addr;
addr -= (sljit_uw)SLJIT_ADD_EXEC_OFFSET(buf_ptr, executable_offset);
if (jump->flags & PATCH_B) {
+ SLJIT_ASSERT(RISCV_HAS_COMPRESSED(200) || !(jump->flags & PATCH_16));
SLJIT_ASSERT((sljit_sw)addr >= BRANCH_MIN && (sljit_sw)addr <= BRANCH_MAX);
- addr = ((addr & 0x800) >> 4) | ((addr & 0x1e) << 7) | ((addr & 0x7e0) << 20) | ((addr & 0x1000) << 19);
- buf_ptr[0] |= (sljit_ins)addr;
+
+ if (RISCV_COMPRESSED_CHECK(jump->flags & PATCH_16)) {
+ buf_ptr[0] |= C_BRN16(addr);
+ break;
+ }
+
+ buf_ptr[0] |= (sljit_u16)(((addr & 0x800) >> 4) | ((addr & 0x1e) << 7));
+ buf_ptr[1] |= (sljit_u16)(((addr & 0x7e0) << 4) | ((addr & 0x1000) << 3));
+ break;
+ }
+
+ SLJIT_ASSERT(RISCV_HAS_COMPRESSED(200) || !(jump->flags & PATCH_16));
+ if (RISCV_COMPRESSED_CHECK(jump->flags & PATCH_16)) {
+ SLJIT_ASSERT((sljit_sw)addr >= JUMP16_MIN && (sljit_sw)addr <= JUMP16_MAX);
+#if defined SLJIT_CONFIG_RISCV_32
+ ins = ((jump->flags & IS_CALL) ? C_JAL : C_J) | C_JMP16(addr);
+#else /* !SLJIT_CONFIG_RISCV_32 */
+ SLJIT_ASSERT(!(jump->flags & IS_CALL));
+ ins = C_J | C_JMP16(addr);
+#endif /* SLJIT_CONFIG_RISCV_32 */
+ buf_ptr[0] = (sljit_u16)ins;
break;
}
SLJIT_ASSERT((sljit_sw)addr >= JUMP_MIN && (sljit_sw)addr <= JUMP_MAX);
addr = (addr & 0xff000) | ((addr & 0x800) << 9) | ((addr & 0x7fe) << 20) | ((addr & 0x100000) << 11);
- buf_ptr[0] = JAL | RD((jump->flags & IS_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | (sljit_ins)addr;
+ ins = JAL | RD((jump->flags & IS_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | (sljit_ins)addr;
+ buf_ptr[0] = (sljit_u16)ins;
+ buf_ptr[1] = (sljit_u16)(ins >> 16);
} while (0);
jump = jump->next;
@@ -719,8 +1067,8 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
compiler->executable_offset = executable_offset;
compiler->executable_size = (sljit_uw)(code_ptr - code) * sizeof(sljit_ins);
- code = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
- code_ptr = (sljit_ins *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ code = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code, executable_offset);
+ code_ptr = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
SLJIT_CACHE_FLUSH(code, code_ptr);
SLJIT_UPDATE_WX_FLAGS(code, code_ptr, 1);
@@ -744,18 +1092,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_has_cpu_feature(sljit_s32 feature_type)
case SLJIT_HAS_COPY_F64:
#endif /* !SLJIT_CONFIG_RISCV_64 */
case SLJIT_HAS_ATOMIC:
+ return RISCV_HAS_ATOMIC(200) ? 1 : 0;
case SLJIT_HAS_MEMORY_BARRIER:
-#ifdef __riscv_vector
- case SLJIT_HAS_SIMD:
-#endif /* __riscv_vector */
return 1;
-#ifdef __riscv_zbb
case SLJIT_HAS_CLZ:
case SLJIT_HAS_CTZ:
case SLJIT_HAS_REV:
case SLJIT_HAS_ROT:
- return 1;
-#endif /* __riscv_zbb */
+ return RISCV_HAS_BITMANIP_B(93) ? 1 : 0;
+ case SLJIT_HAS_CMOV:
+ return RISCV_HAS_ICOND(100) ? 2 : 0;
+ case SLJIT_HAS_SIMD:
+ return RISCV_HAS_VECTOR(100) ? 1 : 0;
default:
return 0;
}
@@ -813,9 +1161,15 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_cmp_info(sljit_s32 type)
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
#define STACK_STORE SW
#define STACK_LOAD LW
+#define C_STACK_OFFSET_CHECK(offset) ((offset) <= 0xfc)
+#define C_STACK_LOAD(offset) (C_LWSP | C_LD32_SP(offset))
+#define C_STACK_STORE(offset) (C_SWSP | C_ST32_SP(offset))
#else /* !SLJIT_CONFIG_RISCV_32 */
#define STACK_STORE SD
#define STACK_LOAD LD
+#define C_STACK_OFFSET_CHECK(offset) ((offset) <= 0x1f8)
+#define C_STACK_LOAD(offset) (C_LDSP | C_LD64_SP(offset))
+#define C_STACK_STORE(offset) (C_SDSP | C_ST64_SP(offset))
#endif /* SLJIT_CONFIG_RISCV_32 */
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
@@ -858,8 +1212,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
if (local_size <= STACK_MAX_DISTANCE) {
/* Frequent case. */
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(-local_size)));
offset = local_size - SSIZE_OF(sw);
+ local_size = -local_size;
+ if (RISCV_HAS_COMPRESSED(200) && local_size >= -0x200) {
+ SLJIT_ASSERT((local_size & 0x200) != 0 && (local_size & 0xf) == 0);
+ FAIL_IF(push_inst16(compiler, C_ADDI16SP | (sljit_u16)(((local_size & 0x10) << 2) | ((local_size & 0x20) >> 3) | ((local_size & 0x40) >> 1) | ((local_size & 0x180) >> 4) | (1 << 12))));
+ } else
+ FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(local_size)));
local_size = 0;
} else {
FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(STACK_MAX_DISTANCE)));
@@ -870,17 +1229,26 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
offset = STACK_MAX_DISTANCE - SSIZE_OF(sw);
}
- FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(RETURN_ADDR_REG), offset));
+ if (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))
+ FAIL_IF(push_inst16(compiler, C_STACK_STORE(offset) | C_RS2(RETURN_ADDR_REG)));
+ else
+ FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(RETURN_ADDR_REG), offset));
tmp = SLJIT_S0 - saveds;
for (i = SLJIT_S0 - saved_arg_count; i > tmp; i--) {
offset -= SSIZE_OF(sw);
- FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));
+ if (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))
+ FAIL_IF(push_inst16(compiler, C_STACK_STORE(offset) | C_RS2(i)));
+ else
+ FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));
}
for (i = scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
offset -= SSIZE_OF(sw);
- FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));
+ if (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))
+ FAIL_IF(push_inst16(compiler, C_STACK_STORE(offset) | C_RS2(i)));
+ else
+ FAIL_IF(push_imm_s_inst(compiler, STACK_STORE | RS1(SLJIT_SP) | RS2(i), offset));
}
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
@@ -892,12 +1260,18 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
tmp = SLJIT_FS0 - fsaveds;
for (i = SLJIT_FS0; i > tmp; i--) {
offset -= SSIZE_OF(f64);
- FAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));
+ if (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)
+ FAIL_IF(push_inst16(compiler, C_FSDSP | C_FRS2(i) | C_ST64_SP(offset)));
+ else
+ FAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));
}
for (i = fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
offset -= SSIZE_OF(f64);
- FAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));
+ if (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)
+ FAIL_IF(push_inst16(compiler, C_FSDSP | C_FRS2(i) | C_ST64_SP(offset)));
+ else
+ FAIL_IF(push_imm_s_inst(compiler, FSD | RS1(SLJIT_SP) | FRS2(i), offset));
}
if (local_size > STACK_MAX_DISTANCE)
@@ -915,7 +1289,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_enter(struct sljit_compiler *compi
while (arg_types > 0) {
if ((arg_types & SLJIT_ARG_MASK) < SLJIT_ARG_TYPE_F64) {
if (!(arg_types & SLJIT_ARG_TYPE_SCRATCH_REG)) {
- FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_S0 - saved_arg_count) | RS1(tmp) | IMM_I(0)));
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_MV | C_RD(SLJIT_S0 - saved_arg_count) | C_RS2(tmp)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(SLJIT_S0 - saved_arg_count) | RS1(tmp) | IMM_I(0)));
saved_arg_count++;
}
tmp++;
@@ -979,18 +1356,28 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit
SLJIT_ASSERT(local_size > 0);
offset = local_size - SSIZE_OF(sw);
- if (!is_return_to)
- FAIL_IF(push_inst(compiler, STACK_LOAD | RD(RETURN_ADDR_REG) | RS1(SLJIT_SP) | IMM_I(offset)));
+ if (!is_return_to) {
+ if (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))
+ FAIL_IF(push_inst16(compiler, C_STACK_LOAD(offset) | C_RD(RETURN_ADDR_REG)));
+ else
+ FAIL_IF(push_inst(compiler, STACK_LOAD | RD(RETURN_ADDR_REG) | RS1(SLJIT_SP) | IMM_I(offset)));
+ }
tmp = SLJIT_S0 - compiler->saveds;
for (i = SLJIT_S0 - SLJIT_KEPT_SAVEDS_COUNT(compiler->options); i > tmp; i--) {
offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
+ if (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))
+ FAIL_IF(push_inst16(compiler, C_STACK_LOAD(offset) | C_RD(i)));
+ else
+ FAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
}
for (i = compiler->scratches; i >= SLJIT_FIRST_SAVED_REG; i--) {
offset -= SSIZE_OF(sw);
- FAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
+ if (RISCV_HAS_COMPRESSED(200) && C_STACK_OFFSET_CHECK(offset))
+ FAIL_IF(push_inst16(compiler, C_STACK_LOAD(offset) | C_RD(i)));
+ else
+ FAIL_IF(push_inst(compiler, STACK_LOAD | RD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
}
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
@@ -1002,12 +1389,23 @@ static sljit_s32 emit_stack_frame_release(struct sljit_compiler *compiler, sljit
tmp = SLJIT_FS0 - compiler->fsaveds;
for (i = SLJIT_FS0; i > tmp; i--) {
offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
+ if (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)
+ FAIL_IF(push_inst16(compiler, C_FLDSP | C_FRD(i) | C_LD64_SP(offset)));
+ else
+ FAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
}
for (i = compiler->fscratches; i >= SLJIT_FIRST_SAVED_FLOAT_REG; i--) {
offset -= SSIZE_OF(f64);
- FAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
+ if (RISCV_HAS_COMPRESSED(200) && offset <= 0x1f8)
+ FAIL_IF(push_inst16(compiler, C_FLDSP | C_FRD(i) | C_LD64_SP(offset)));
+ else
+ FAIL_IF(push_inst(compiler, FLD | FRD(i) | RS1(SLJIT_SP) | IMM_I(offset)));
+ }
+
+ if (RISCV_HAS_COMPRESSED(200) && local_size <= 0x1f0) {
+ SLJIT_ASSERT((local_size & 0xf) == 0);
+ return push_inst16(compiler, C_ADDI16SP | (sljit_u16)(((local_size & 0x10) << 2) | ((local_size & 0x20) >> 3) | ((local_size & 0x40) >> 1) | ((local_size & 0x180) >> 4)));
}
return push_inst(compiler, ADDI | RD(SLJIT_SP) | RS1(SLJIT_SP) | IMM_I(local_size));
@@ -1087,14 +1485,80 @@ static const sljit_ins data_transfer_insts[16 + 4] = {
static sljit_s32 push_mem_inst(struct sljit_compiler *compiler, sljit_s32 flags, sljit_s32 reg, sljit_s32 base, sljit_sw offset)
{
sljit_ins ins;
+ sljit_s32 signed_flags;
+ sljit_s32 load_flags;
SLJIT_ASSERT(FAST_IS_REG(base) && offset <= 0xfff && offset >= SIMM_MIN);
- ins = data_transfer_insts[flags & MEM_MASK] | RS1(base);
+ flags &= MEM_MASK;
+
+ if (RISCV_HAS_COMPRESSED(200) && offset >= 0) {
+ if (base == SLJIT_SP) {
+ signed_flags = flags | SIGNED_DATA;
+
+ if ((offset & 0x3) == 0 && offset <= 0xfc) {
+#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
+ if ((signed_flags == (SIGNED_DATA | LOAD_DATA) || signed_flags == (INT_DATA | SIGNED_DATA | LOAD_DATA)))
+ return push_inst16(compiler, C_LWSP | C_RD(reg) | C_LD32_SP(offset));
+ if ((signed_flags == SIGNED_DATA || signed_flags == (INT_DATA | SIGNED_DATA)))
+ return push_inst16(compiler, C_SWSP | C_RS2(reg) | C_ST32_SP(offset));
+ if (flags == (SINGLE_DATA | LOAD_DATA))
+ return push_inst16(compiler, C_FLWSP | C_FRD(reg) | C_LD32_SP(offset));
+ if (flags == SINGLE_DATA)
+ return push_inst16(compiler, C_FSWSP | C_FRS2(reg) | C_ST32_SP(offset));
+#else /* !SLJIT_CONFIG_RISCV_32 */
+ if (flags == (INT_DATA | SIGNED_DATA | LOAD_DATA))
+ return push_inst16(compiler, C_LWSP | C_RD(reg) | C_LD32_SP(offset));
+ if (signed_flags == (INT_DATA | SIGNED_DATA))
+ return push_inst16(compiler, C_SWSP | C_RS2(reg) | C_ST32_SP(offset));
+#endif /* SLJIT_CONFIG_RISCV_32 */
+ }
+
+ if ((offset & 0x7) == 0 && offset <= 0x1f8) {
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ if (signed_flags == (SIGNED_DATA | LOAD_DATA))
+ return push_inst16(compiler, C_LDSP | C_RD(reg) | C_LD64_SP(offset));
+ if (signed_flags == SIGNED_DATA)
+ return push_inst16(compiler, C_SDSP | C_RS2(reg) | C_ST64_SP(offset));
+#endif /* SLJIT_CONFIG_RISCV_64 */
+ if (flags == (DOUBLE_DATA | LOAD_DATA))
+ return push_inst16(compiler, C_FLDSP | C_FRD(reg) | C_LD64_SP(offset));
+ if (flags == DOUBLE_DATA)
+ return push_inst16(compiler, C_FSDSP | C_FRS2(reg) | C_ST64_SP(offset));
+ }
+ } else if (C_IS_R3(base) && (flags <= GPR_REG ? C_IS_R3(reg) : C_IS_FR3(reg))) {
+ SLJIT_COMPILE_ASSERT(LOAD_DATA == 1, load_data_bit_error);
+ signed_flags = flags | LOAD_DATA | SIGNED_DATA;
+ load_flags = flags | LOAD_DATA;
+
+ if ((offset & 0x3) == 0 && offset <= 0x7c) {
+#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
+ if (signed_flags == (SIGNED_DATA | LOAD_DATA) || signed_flags == (INT_DATA | SIGNED_DATA | LOAD_DATA))
+ return push_inst16(compiler, (C_SW ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_RS2_R3(reg) | C_MEM32(offset));
+ if (load_flags == (SINGLE_DATA | LOAD_DATA))
+ return push_inst16(compiler, (C_FSW ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_FRS2_R3(reg) | C_MEM32(offset));
+#else /* !SLJIT_CONFIG_RISCV_32 */
+ if (load_flags == (INT_DATA | SIGNED_DATA | LOAD_DATA))
+ return push_inst16(compiler, (C_SW ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_RS2_R3(reg) | C_MEM32(offset));
+#endif /* SLJIT_CONFIG_RISCV_32 */
+ }
+
+ if ((offset & 0x7) == 0 && offset <= 0xf8) {
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ if (signed_flags == (SIGNED_DATA | LOAD_DATA))
+ return push_inst16(compiler, (C_SD ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_RS2_R3(reg) | C_MEM64(offset));
+#endif /* SLJIT_CONFIG_RISCV_64 */
+ if (load_flags == (DOUBLE_DATA | LOAD_DATA))
+ return push_inst16(compiler, (C_FSD ^ (sljit_u16)((flags & LOAD_DATA) << 15)) | C_RS1_R3(base) | C_FRS2_R3(reg) | C_MEM64(offset));
+ }
+ }
+ }
+
+ ins = data_transfer_insts[flags] | RS1(base);
if (flags & LOAD_DATA)
- ins |= ((flags & MEM_MASK) <= GPR_REG ? RD(reg) : FRD(reg)) | IMM_I(offset);
+ ins |= (flags <= GPR_REG ? RD(reg) : FRD(reg)) | IMM_I(offset);
else
- ins |= ((flags & MEM_MASK) <= GPR_REG ? RS2(reg) : FRS2(reg)) | IMM_S(offset);
+ ins |= (flags <= GPR_REG ? RS2(reg) : FRS2(reg)) | IMM_S(offset);
return push_inst(compiler, ins);
}
@@ -1148,9 +1612,7 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
sljit_s32 base = arg & REG_MASK;
sljit_s32 tmp_r = (flags & MEM_USE_TMP2) ? TMP_REG2 : TMP_REG1;
sljit_sw offset, argw_hi;
-#if defined __riscv_zba
sljit_ins ins = ADD;
-#endif /* __riscv_zba */
SLJIT_ASSERT(arg & SLJIT_MEM);
if (!(next_arg & SLJIT_MEM)) {
@@ -1161,20 +1623,22 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
if (SLJIT_UNLIKELY(arg & OFFS_REG_MASK)) {
argw &= 0x3;
-#if defined __riscv_zba
- switch (argw) {
- case 1:
- ins = SH1ADD;
- break;
- case 2:
- ins = SH2ADD;
- break;
- case 3:
- ins = SH3ADD;
- break;
+ if (RISCV_HAS_BITMANIP_A(93)) {
+ switch (argw) {
+ case 1:
+ ins = SH1ADD;
+ break;
+ case 2:
+ ins = SH2ADD;
+ break;
+ case 3:
+ ins = SH3ADD;
+ break;
+ }
+ FAIL_IF(push_inst(compiler, ins | RD(tmp_r) | RS1(OFFS_REG(arg)) | RS2(base)));
+ return push_mem_inst(compiler, flags, reg, tmp_r, 0);
}
- FAIL_IF(push_inst(compiler, ins | RD(tmp_r) | RS1(OFFS_REG(arg)) | RS2(base)));
-#else /* !__riscv_zba */
+
/* Using the cache. */
if (argw == compiler->cache_argw) {
if (arg == compiler->cache_arg)
@@ -1206,7 +1670,6 @@ static sljit_s32 getput_arg(struct sljit_compiler *compiler, sljit_s32 flags, sl
}
else
FAIL_IF(push_inst(compiler, ADD | RD(tmp_r) | RS1(base) | RS2(!argw ? OFFS_REG(arg) : TMP_REG3)));
-#endif /* __riscv_zba */
return push_mem_inst(compiler, flags, reg, tmp_r, 0);
}
@@ -1294,7 +1757,27 @@ static SLJIT_INLINE sljit_s32 emit_op_mem2(struct sljit_compiler *compiler, slji
#define WORD_32 0x08
#define IMM_EXTEND(v) (IMM_I((op & SLJIT_32) ? (v) : (32 + (v))))
#endif /* SLJIT_CONFIG_RISCV_32 */
-#ifndef __riscv_zbb
+
+static sljit_s32 emit_add(struct sljit_compiler *compiler, sljit_ins word, sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
+{
+ SLJIT_UNUSED_ARG(word);
+
+ if (dst == src2) {
+ src2 = src1;
+ src1 = dst;
+ }
+
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1) {
+ if (WORD == 0 && src2 != 0)
+ return push_inst16(compiler, C_ADD | C_RD(dst) | C_RS2(src2));
+
+ if (WORD == 0x8 && C_IS_R3(dst) && C_IS_R3(src2))
+ return push_inst16(compiler, C_ADDW | C_RS1_R3(dst) | C_RS2_R3(src2));
+ }
+
+ return push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2));
+}
+
static sljit_s32 emit_clz_ctz(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 dst, sljit_sw src)
{
sljit_s32 is_clz = (GET_OPCODE(op) == SLJIT_CLZ);
@@ -1378,7 +1861,11 @@ static sljit_s32 emit_rev(struct sljit_compiler *compiler, sljit_s32 op, sljit_s
FAIL_IF(push_inst(compiler, SRLI | WORD_32 | RD(TMP_REG1) | RS1(dst) | IMM_I(8)));
FAIL_IF(push_inst(compiler, AND | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));
FAIL_IF(push_inst(compiler, AND | RD(TMP_REG1) | RS1(TMP_REG1) | RS2(OTHER_FLAG)));
- FAIL_IF(push_inst(compiler, SLLI | WORD_32 | RD(dst) | RS1(dst) | IMM_I(8)));
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ FAIL_IF(push_inst(compiler, SLLI | (GET_OPCODE(op) == SLJIT_REV_S32 ? WORD_32 : 0) | RD(dst) | RS1(dst) | IMM_I(8)));
+#else /* !SLJIT_CONFIG_RISCV_64 */
+ FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(8)));
+#endif /* SLJIT_CONFIG_RISCV_64 */
return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1));
}
@@ -1397,26 +1884,33 @@ static sljit_s32 emit_rev16(struct sljit_compiler *compiler, sljit_s32 op, sljit
FAIL_IF(push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | WORD | RD(dst) | RS1(dst) | IMM_I(word_size - 16)));
return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(TMP_REG1));
}
-#endif /* !__riscv_zbb */
-#define EMIT_LOGICAL(op_imm, op_reg) \
+#define EMIT_LOGICAL(op_imm, op_c_imm, op_reg, op_c_reg) \
if (flags & SRC2_IMM) { \
if (op & SLJIT_SET_Z) \
FAIL_IF(push_inst(compiler, op_imm | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2))); \
- if (!(flags & UNUSED_DEST)) \
- FAIL_IF(push_inst(compiler, op_imm | RD(dst) | RS1(src1) | IMM_I(src2))); \
- } \
- else { \
+ if (!(flags & UNUSED_DEST)) { \
+ if (op_c_imm != 0 && RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN && C_IS_R3(dst)) \
+ FAIL_IF(push_inst16(compiler, op_c_imm | C_RS1_R3(dst) | C_IMM_I(src2))); \
+ else \
+ FAIL_IF(push_inst(compiler, op_imm | RD(dst) | RS1(src1) | IMM_I(src2))); \
+ } \
+ } else { \
+ if (dst == src2) { \
+ src2 = src1; \
+ src1 = dst; \
+ } \
+ \
if (op & SLJIT_SET_Z) \
FAIL_IF(push_inst(compiler, op_reg | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2))); \
- if (!(flags & UNUSED_DEST)) \
- FAIL_IF(push_inst(compiler, op_reg | RD(dst) | RS1(src1) | RS2(src2))); \
+ if (!(flags & UNUSED_DEST)) { \
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2)) \
+ FAIL_IF(push_inst16(compiler, op_c_reg | C_RS1_R3(dst) | C_RS2_R3(src2))); \
+ else \
+ FAIL_IF(push_inst(compiler, op_reg | RD(dst) | RS1(src1) | RS2(src2))); \
+ } \
}
-#define EMIT_SHIFT(imm, reg) \
- op_imm = (imm); \
- op_reg = (reg);
-
static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sljit_s32 op, sljit_s32 flags,
sljit_s32 dst, sljit_s32 src1, sljit_sw src2)
{
@@ -1431,9 +1925,16 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
switch (GET_OPCODE(op)) {
case SLJIT_MOV:
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
- if (dst != src2)
+ if (dst == src2)
+ return SLJIT_SUCCESS;
+
+ if (!RISCV_HAS_COMPRESSED(200))
return push_inst(compiler, ADDI | RD(dst) | RS1(src2) | IMM_I(0));
- return SLJIT_SUCCESS;
+
+ /* Revert the x0 to immediate 0. */
+ if (src2 == 0)
+ return push_inst16(compiler, C_LI | C_RD(dst));
+ return push_inst16(compiler, C_MV | C_RD(dst) | C_RS2(src2));
case SLJIT_MOV_U8:
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
@@ -1443,9 +1944,9 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
return SLJIT_SUCCESS;
case SLJIT_MOV_S8:
-#if defined __riscv_zbb
- return push_inst(compiler, SEXTB | RD(dst) | RS1(src2));
-#else /* !__riscv_zbb */
+ if (RISCV_HAS_BITMANIP_B(93))
+ return push_inst(compiler, SEXTB | RD(dst) | RS1(src2));
+
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(24)));
@@ -1453,12 +1954,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
}
SLJIT_ASSERT(dst == src2);
return SLJIT_SUCCESS;
-#endif /* __riscv_zbb */
case SLJIT_MOV_U16:
-#if defined __riscv_zbb
- return push_inst(compiler, ZEXTH | RD(dst) | RS1(src2));
-#else /* !__riscv_zbb */
+ if (RISCV_HAS_BITMANIP_B(93))
+ return push_inst(compiler, ZEXTH | RD(dst) | RS1(src2));
+
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));
@@ -1466,12 +1966,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
}
SLJIT_ASSERT(dst == src2);
return SLJIT_SUCCESS;
-#endif /* __riscv_zbb */
case SLJIT_MOV_S16:
-#if defined __riscv_zbb
- return push_inst(compiler, SEXTH | RD(dst) | RS1(src2));
-#else /* !__riscv_zbb */
+ if (RISCV_HAS_BITMANIP_B(93))
+ return push_inst(compiler, SEXTH | RD(dst) | RS1(src2));
+
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
FAIL_IF(push_inst(compiler, SLLI | WORD | RD(dst) | RS1(src2) | IMM_EXTEND(16)));
@@ -1479,7 +1978,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
}
SLJIT_ASSERT(dst == src2);
return SLJIT_SUCCESS;
-#endif /* !__riscv_zbb */
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
case SLJIT_MOV_U32:
@@ -1493,74 +1991,54 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
case SLJIT_MOV_S32:
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
- if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE))
+ if ((flags & (REG_DEST | REG2_SOURCE)) == (REG_DEST | REG2_SOURCE)) {
+ if (RISCV_HAS_COMPRESSED(200) && dst == src2)
+ return push_inst16(compiler, C_ADDIW | C_RD(dst));
return push_inst(compiler, ADDI | 0x8 | RD(dst) | RS1(src2) | IMM_I(0));
+ }
SLJIT_ASSERT(dst == src2);
return SLJIT_SUCCESS;
#endif /* SLJIT_CONFIG_RISCV_64 */
case SLJIT_CLZ:
-#if defined __riscv_zbb
- return push_inst(compiler, CLZ | WORD | RD(dst) | RS1(src2));
-#endif /* __riscv_zbb */
case SLJIT_CTZ:
-#if defined __riscv_zbb
- return push_inst(compiler, CTZ | WORD | RD(dst) | RS1(src2));
-#else /* !__riscv_zbb */
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
+ if (RISCV_HAS_BITMANIP_B(93))
+ return push_inst(compiler, ((GET_OPCODE(op) == SLJIT_CLZ) ? CLZ : CTZ) | WORD | RD(dst) | RS1(src2));
+
return emit_clz_ctz(compiler, op, dst, src2);
-#endif /* __riscv_zbb */
case SLJIT_REV:
-#if defined __riscv_zbb
- SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
- FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2)));
-#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64
- if (op & SLJIT_32)
- return push_inst(compiler, SRAI | RD(dst) | RS1(dst) | IMM_I(32));
- return SLJIT_SUCCESS;
-#else /* !SLJIT_CONFIG_RISCV_64 */
- return SLJIT_SUCCESS;
-#endif /* SLJIT_CONFIG_RISCV_64 */
-#endif /* __riscv_zbb */
case SLJIT_REV_S32:
-#if ((defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32) || defined __riscv_zbb)
case SLJIT_REV_U32:
-#endif /* SLJIT_CONFIG_RISCV_32 || __riscv_zbb */
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
-#if defined __riscv_zbb
- FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2)));
+ if (RISCV_HAS_BITMANIP_B(93)) {
#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64
- return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U32 ? SRLI : SRAI )| RD(dst) | RS1(dst) | IMM_I(32));
+ FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2)));
+ if ((op & SLJIT_32) || GET_OPCODE(op) != SLJIT_REV)
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U32 ? SRLI : SRAI)| RD(dst) | RS1(dst) | IMM_I(32));
+ return SLJIT_SUCCESS;
#else /* !SLJIT_CONFIG_RISCV_64 */
- return SLJIT_SUCCESS;
+ return push_inst(compiler, REV8 | RD(dst) | RS1(src2));
#endif /* SLJIT_CONFIG_RISCV_64 */
-#else /* !__riscv_zbb */
+ }
+
return emit_rev(compiler, op, dst, src2);
-#endif /* __riscv_zbb */
+
case SLJIT_REV_U16:
case SLJIT_REV_S16:
SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM));
-#if defined __riscv_zbb
- FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2)));
+ if (RISCV_HAS_BITMANIP_B(93)) {
+ FAIL_IF(push_inst(compiler, REV8 | RD(dst) | RS1(src2)));
#if defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64
- return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI )| RD(dst) | RS1(dst) | IMM_I(48));
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI)| RD(dst) | RS1(dst) | IMM_I(48));
#else /* !SLJIT_CONFIG_RISCV_64 */
- return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | RD(dst) | RS1(dst) | IMM_I(16));
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_REV_U16 ? SRLI : SRAI) | RD(dst) | RS1(dst) | IMM_I(16));
#endif /* SLJIT_CONFIG_RISCV_64 */
-#else /* !__riscv_zbb */
+ }
+
return emit_rev16(compiler, op, dst, src2);
-#endif /* __riscv_zbb */
-#if ((defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64) && !defined __riscv_zbb)
- case SLJIT_REV_U32:
- SLJIT_ASSERT(src1 == TMP_ZERO && !(flags & SRC2_IMM) && dst != TMP_REG1);
- FAIL_IF(emit_rev(compiler, op, dst, src2));
- if (dst == TMP_REG2)
- return SLJIT_SUCCESS;
- FAIL_IF(push_inst(compiler, SLLI | RD(dst) | RS1(dst) | IMM_I(32)));
- return push_inst(compiler, SRLI | RD(dst) | RS1(dst) | IMM_I(32));
-#endif /* SLJIT_CONFIG_RISCV_64 && !__riscv_zbb */
case SLJIT_ADD:
/* Overflow computation (both add and sub): overflow = src1_sign ^ src2_sign ^ result_sign ^ carry_flag */
is_overflow = GET_FLAG_TYPE(op) == SLJIT_OVERFLOW;
@@ -1568,19 +2046,26 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (flags & SRC2_IMM) {
if (is_overflow) {
- if (src2 >= 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
- else
+ if (src2 >= 0) {
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(src1)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
+ } else
FAIL_IF(push_inst(compiler, XORI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-1)));
}
else if (op & SLJIT_SET_Z)
FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));
/* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
- }
- else {
+ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) {
+ SLJIT_ASSERT(src2 != 0);
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)
+ FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
+ }
+ } else {
if (is_overflow)
FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
else if (op & SLJIT_SET_Z)
@@ -1599,7 +2084,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
/* Only the zero flag is needed. */
if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2)));
+ FAIL_IF(emit_add(compiler, WORD, dst, src1, src2));
}
/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
@@ -1614,8 +2099,12 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
return SLJIT_SUCCESS;
FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RS1(dst) | RS2(EQUAL_FLAG)));
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));
+ if (op & SLJIT_SET_Z) {
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(dst)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));
+ }
FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_EXTEND(31)));
return push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG));
@@ -1623,7 +2112,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
carry_src_r = GET_FLAG_TYPE(op) == SLJIT_CARRY;
if (flags & SRC2_IMM) {
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
+ SLJIT_ASSERT(src2 != 0);
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)
+ FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
} else {
if (carry_src_r != 0) {
if (src1 != dst)
@@ -1631,12 +2124,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
else if (src2 != dst)
carry_src_r = (sljit_s32)src2;
else {
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(src1)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
carry_src_r = EQUAL_FLAG;
}
}
- FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(src1) | RS2(src2)));
+ FAIL_IF(emit_add(compiler, WORD, dst, src1, src2));
}
/* Carry is zero if a + b >= a or a + b >= b, otherwise it is 1. */
@@ -1647,7 +2143,10 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
FAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RS1(dst) | RS2(carry_src_r)));
}
- FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));
+ if (RISCV_HAS_COMPRESSED(200) && WORD == 0)
+ FAIL_IF(push_inst16(compiler, C_ADD | C_RD(dst) | C_RS2(OTHER_FLAG)));
+ else
+ FAIL_IF(push_inst(compiler, ADD | WORD | RD(dst) | RS1(dst) | RS2(OTHER_FLAG)));
if (carry_src_r == 0)
return SLJIT_SUCCESS;
@@ -1670,8 +2169,7 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (GET_FLAG_TYPE(op) == SLJIT_LESS) {
FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
is_handled = 1;
- }
- else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {
+ } else if (GET_FLAG_TYPE(op) == SLJIT_SIG_LESS) {
FAIL_IF(push_inst(compiler, SLTI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
is_handled = 1;
}
@@ -1682,7 +2180,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (flags & SRC2_IMM) {
reg = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
- FAIL_IF(push_inst(compiler, ADDI | RD(reg) | RS1(TMP_ZERO) | IMM_I(src2)));
+ if (RISCV_HAS_COMPRESSED(200) && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)
+ FAIL_IF(push_inst16(compiler, C_LI | C_RD(reg) | C_IMM_I(src2)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(reg) | RS1(TMP_ZERO) | IMM_I(src2)));
+
src2 = reg;
flags &= ~SRC2_IMM;
}
@@ -1707,14 +2209,22 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (flags & SRC2_IMM) {
if (op & SLJIT_SET_Z)
FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-src2)));
- if (!(flags & UNUSED_DEST))
- return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(-src2));
- }
- else {
+ if (!(flags & UNUSED_DEST)) {
+ src2 = -src2;
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)
+ return push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2));
+
+ return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2));
+ }
+ } else {
if (op & SLJIT_SET_Z)
FAIL_IF(push_inst(compiler, SUB | WORD | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
- if (!(flags & UNUSED_DEST))
+ if (!(flags & UNUSED_DEST)) {
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2))
+ return push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2));
+
return push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2));
+ }
}
return SLJIT_SUCCESS;
}
@@ -1724,22 +2234,28 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (flags & SRC2_IMM) {
if (is_overflow) {
- if (src2 >= 0)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
- else
+ if (src2 >= 0) {
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(src1)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(0)));
+ } else
FAIL_IF(push_inst(compiler, XORI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-1)));
- }
- else if (op & SLJIT_SET_Z)
+ } else if (op & SLJIT_SET_Z)
FAIL_IF(push_inst(compiler, ADDI | WORD | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(-src2)));
if (is_overflow || is_carry)
FAIL_IF(push_inst(compiler, SLTUI | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
/* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(-src2)));
- }
- else {
+ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) {
+ src2 = -src2;
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)
+ FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
+ }
+ } else {
if (is_overflow)
FAIL_IF(push_inst(compiler, XOR | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
else if (op & SLJIT_SET_Z)
@@ -1749,16 +2265,24 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2)));
/* Only the zero flag is needed. */
- if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK))
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));
+ if (!(flags & UNUSED_DEST) || (op & VARIABLE_FLAG_MASK)) {
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2))
+ FAIL_IF(push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2)));
+ else
+ FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));
+ }
}
if (!is_overflow)
return SLJIT_SUCCESS;
FAIL_IF(push_inst(compiler, XOR | RD(TMP_REG1) | RS1(dst) | RS2(EQUAL_FLAG)));
- if (op & SLJIT_SET_Z)
- FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));
+ if (op & SLJIT_SET_Z) {
+ if (RISCV_HAS_COMPRESSED(200))
+ FAIL_IF(push_inst16(compiler, C_MV | C_RD(EQUAL_FLAG) | C_RS2(dst)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(EQUAL_FLAG) | RS1(dst) | IMM_I(0)));
+ }
FAIL_IF(push_inst(compiler, SRLI | WORD | RD(TMP_REG1) | RS1(TMP_REG1) | IMM_EXTEND(31)));
return push_inst(compiler, XOR | RD(OTHER_FLAG) | RS1(TMP_REG1) | RS2(OTHER_FLAG));
@@ -1775,13 +2299,19 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (is_carry)
FAIL_IF(push_inst(compiler, SLTUI | RD(EQUAL_FLAG) | RS1(src1) | IMM_I(src2)));
- FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(-src2)));
- }
- else {
+ src2 = -src2;
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && src2 <= SIMM16_MAX && src2 >= SIMM16_MIN)
+ FAIL_IF(push_inst16(compiler, C_ADDI_W(WORD) | C_RD(dst) | C_IMM_I(src2)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
+ } else {
if (is_carry)
FAIL_IF(push_inst(compiler, SLTU | RD(EQUAL_FLAG) | RS1(src1) | RS2(src2)));
- FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));
+ if (RISCV_HAS_COMPRESSED(200) && dst == src1 && C_IS_R3(dst) && C_IS_R3(src2))
+ FAIL_IF(push_inst16(compiler, C_SUB_W(WORD) | C_RS1_R3(dst) | C_RS2_R3(src2)));
+ else
+ FAIL_IF(push_inst(compiler, SUB | WORD | RD(dst) | RS1(src1) | RS2(src2)));
}
if (is_carry)
@@ -1818,46 +2348,51 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
return push_inst(compiler, SUB | RD(OTHER_FLAG) | RS1(EQUAL_FLAG) | RS2(OTHER_FLAG));
case SLJIT_AND:
- EMIT_LOGICAL(ANDI, AND);
+ EMIT_LOGICAL(ANDI, C_ANDI, AND, C_AND);
return SLJIT_SUCCESS;
case SLJIT_OR:
- EMIT_LOGICAL(ORI, OR);
+ EMIT_LOGICAL(ORI, 0, OR, C_OR);
return SLJIT_SUCCESS;
case SLJIT_XOR:
- EMIT_LOGICAL(XORI, XOR);
+ EMIT_LOGICAL(XORI, 0, XOR, C_XOR);
return SLJIT_SUCCESS;
case SLJIT_SHL:
case SLJIT_MSHL:
- EMIT_SHIFT(SLLI, SLL);
+ op_imm = SLLI;
+ op_reg = SLL;
break;
case SLJIT_LSHR:
case SLJIT_MLSHR:
- EMIT_SHIFT(SRLI, SRL);
+ op_imm = SRLI;
+ op_reg = SRL;
break;
case SLJIT_ASHR:
case SLJIT_MASHR:
- EMIT_SHIFT(SRAI, SRA);
+ op_imm = SRAI;
+ op_reg = SRA;
break;
case SLJIT_ROTL:
case SLJIT_ROTR:
if (flags & SRC2_IMM) {
SLJIT_ASSERT(src2 != 0);
-#if defined __riscv_zbb
- if (GET_OPCODE(op) == SLJIT_ROTL) {
+
+ if (RISCV_HAS_BITMANIP_B(93)) {
+ if (GET_OPCODE(op) == SLJIT_ROTL) {
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- src2 = ((op & SLJIT_32) ? 32 : 64) - src2;
+ src2 = ((op & SLJIT_32) ? 32 : 64) - src2;
#else /* !SLJIT_CONFIG_RISCV_64 */
- src2 = 32 - src2;
+ src2 = 32 - src2;
#endif /* SLJIT_CONFIG_RISCV_64 */
+ }
+ return push_inst(compiler, RORI | WORD | RD(dst) | RS1(src1) | IMM_I(src2));
}
- return push_inst(compiler, RORI | WORD | RD(dst) | RS1(src1) | IMM_I(src2));
-#else /* !__riscv_zbb */
+
op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SLLI : SRLI;
FAIL_IF(push_inst(compiler, op_imm | WORD | RD(OTHER_FLAG) | RS1(src1) | IMM_I(src2)));
@@ -1869,12 +2404,11 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
op_imm = (GET_OPCODE(op) == SLJIT_ROTL) ? SRLI : SLLI;
FAIL_IF(push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2)));
return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG));
-#endif /* !__riscv_zbb */
}
-#if defined __riscv_zbb
- return push_inst(compiler, (GET_OPCODE(op) == SLJIT_ROTL ? ROL : ROR) | WORD | RD(dst) | RS1(src1) | RS2(src2));
-#else /* !__riscv_zbb */
+ if (RISCV_HAS_BITMANIP_B(93))
+ return push_inst(compiler, (GET_OPCODE(op) == SLJIT_ROTL ? ROL : ROR) | WORD | RD(dst) | RS1(src1) | RS2(src2));
+
if (src2 == TMP_ZERO) {
if (dst != src1)
return push_inst(compiler, ADDI | WORD | RD(dst) | RS1(src1) | IMM_I(0));
@@ -1887,7 +2421,6 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
op_reg = (GET_OPCODE(op) == SLJIT_ROTL) ? SRL : SLL;
FAIL_IF(push_inst(compiler, op_reg | WORD | RD(dst) | RS1(src1) | RS2(EQUAL_FLAG)));
return push_inst(compiler, OR | RD(dst) | RS1(dst) | RS2(OTHER_FLAG));
-#endif /* !riscv_zbb */
default:
SLJIT_UNREACHABLE();
return SLJIT_SUCCESS;
@@ -1899,6 +2432,15 @@ static SLJIT_INLINE sljit_s32 emit_single_op(struct sljit_compiler *compiler, sl
if (flags & UNUSED_DEST)
return SLJIT_SUCCESS;
+
+ if (RISCV_HAS_COMPRESSED(200) && WORD == 0 && dst == src1) {
+ if (op_imm == SLLI)
+ return push_inst16(compiler, C_SLLI | C_RD(dst) | C_IMM_I(src2));
+
+ if (C_IS_R3(dst))
+ return push_inst16(compiler, (op_imm == SRLI ? C_SRLI : C_SRAI) | C_RS1_R3(dst) | C_IMM_I(src2));
+ }
+
return push_inst(compiler, op_imm | WORD | RD(dst) | RS1(src1) | IMM_I(src2));
}
@@ -2051,9 +2593,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compile
switch (GET_OPCODE(op)) {
case SLJIT_BREAKPOINT:
+ if (RISCV_HAS_COMPRESSED(200))
+ return push_inst16(compiler, C_EBREAK);
return push_inst(compiler, EBREAK);
case SLJIT_NOP:
- return push_inst(compiler, ADDI | RD(TMP_ZERO) | RS1(TMP_ZERO) | IMM_I(0));
+ if (RISCV_HAS_COMPRESSED(200))
+ return push_inst16(compiler, C_NOP);
+ return push_inst(compiler, NOP);
case SLJIT_LMUL_UW:
FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(SLJIT_R1) | IMM_I(0)));
FAIL_IF(push_inst(compiler, MULHU | RD(SLJIT_R1) | RS1(SLJIT_R0) | RS2(SLJIT_R1)));
@@ -2337,6 +2883,76 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r, tmp_r;
+ sljit_ins ins;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, src2, src2w, src1, src1w));
+ src2 = TMP_REG2;
+ }
+
+ if (src1 == SLJIT_IMM) {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));
+ src1 = TMP_REG1;
+ } else if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem2(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src1, src1w, dst, dstw));
+ src1 = TMP_REG1;
+ }
+
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+ ins = 0;
+
+ if (RISCV_HAS_BITMANIP_A(93)) {
+ switch (shift_arg) {
+ case 1:
+ ins = SH1ADD;
+ break;
+ case 2:
+ ins = SH2ADD;
+ break;
+ case 3:
+ ins = SH3ADD;
+ break;
+ }
+ }
+
+ if (ins == 0) {
+ tmp_r = (src1 == TMP_REG1) ? TMP_REG2 : TMP_REG1;
+ FAIL_IF(push_inst(compiler, SLLI | RD(tmp_r) | RS1(src2) | IMM_I(shift_arg)));
+ FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RS1(src1) | RS2(tmp_r)));
+ } else {
+ FAIL_IF(push_inst(compiler, ins | RD(dst_r) | RS1(src2) | RS2(src1)));
+ }
+
+ if (dst & SLJIT_MEM)
+ return emit_op_mem2(compiler, WORD_DATA, dst_r, dst, dstw, 0, 0);
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -2346,9 +2962,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_RETURN:
- if (FAST_IS_REG(src))
- FAIL_IF(push_inst(compiler, ADDI | RD(RETURN_ADDR_REG) | RS1(src) | IMM_I(0)));
- else
+ if (FAST_IS_REG(src)) {
+ if (src != RETURN_ADDR_REG)
+ FAIL_IF(push_inst(compiler, ADDI | RD(RETURN_ADDR_REG) | RS1(src) | IMM_I(0)));
+ } else
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, RETURN_ADDR_REG, src, srcw));
return push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(RETURN_ADDR_REG) | IMM_I(0));
@@ -2375,8 +2992,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_ENTER:
- if (FAST_IS_REG(dst))
+ if (FAST_IS_REG(dst)) {
+ if (dst == RETURN_ADDR_REG)
+ return SLJIT_SUCCESS;
return push_inst(compiler, ADDI | RD(dst) | RS1(RETURN_ADDR_REG) | IMM_I(0));
+ }
SLJIT_ASSERT(RETURN_ADDR_REG == TMP_REG2);
break;
@@ -2413,6 +3033,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_custom(struct sljit_compiler *c
CHECK_ERROR();
CHECK(check_sljit_emit_op_custom(compiler, instruction, size));
+ if (size == 2)
+ return push_inst16(compiler, *(sljit_u16*)instruction);
+
return push_inst(compiler, *(sljit_ins*)instruction);
}
@@ -2749,11 +3372,80 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
-#define BRANCH_LENGTH ((sljit_ins)(3 * sizeof(sljit_ins)) << 7)
-#else /* !SLJIT_CONFIG_RISCV_32 */
-#define BRANCH_LENGTH ((sljit_ins)(7 * sizeof(sljit_ins)) << 7)
-#endif /* SLJIT_CONFIG_RISCV_32 */
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask = 0, i;
+ struct sljit_label *label = NULL;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (RISCV_HAS_COMPRESSED(200)) {
+ if (alignment <= SLJIT_LABEL_ALIGN_2) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_u16);
+
+ for (i = (mask >> 1); i != 0; i--)
+ PTR_FAIL_IF(push_inst16(compiler, C_NOP));
+ }
+ } else {
+ if (alignment <= SLJIT_LABEL_ALIGN_4) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_ins);
+
+ for (i = (mask >> 2); i != 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+ }
+ }
+
+ if (label == NULL) {
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ if (RISCV_HAS_COMPRESSED(200)) {
+ for (i = (buffers->size + 1) >> 1; i > 0; i--)
+ PTR_FAIL_IF(push_inst16(compiler, C_NOP));
+ } else {
+ for (i = (buffers->size + 3) >> 2; i > 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, NOP));
+ }
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
static sljit_ins get_jump_instruction(sljit_s32 type)
{
@@ -2826,14 +3518,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compile
}
jump->addr = compiler->size;
- inst = JALR | RS1(TMP_REG1) | IMM_I(0);
- if (type >= SLJIT_FAST_CALL) {
+ if (type >= SLJIT_FAST_CALL)
jump->flags |= IS_CALL;
- inst |= RD(RETURN_ADDR_REG);
- }
- PTR_FAIL_IF(push_inst(compiler, inst));
+ PTR_FAIL_IF(push_inst16(compiler, 0));
/* Maximum number of instructions required for generating a constant. */
compiler->size += JUMP_MAX_SIZE - 1;
@@ -2913,9 +3602,37 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
switch (type) {
case SLJIT_EQUAL:
+ if (RISCV_HAS_COMPRESSED(200)) {
+ if (src1 == TMP_ZERO && C_IS_R3(src2)) {
+ inst = C_BNEZ | C_RS1_R3(src2) | BRANCH16_LENGTH;
+ jump->flags |= IS_COND16;
+ break;
+ }
+
+ if (src2 == TMP_ZERO && C_IS_R3(src1)) {
+ inst = C_BNEZ | C_RS1_R3(src1) | BRANCH16_LENGTH;
+ jump->flags |= IS_COND16;
+ break;
+ }
+ }
+
inst = BNE | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
break;
case SLJIT_NOT_EQUAL:
+ if (RISCV_HAS_COMPRESSED(200)) {
+ if (src1 == TMP_ZERO && C_IS_R3(src2)) {
+ inst = C_BEQZ | C_RS1_R3(src2) | BRANCH16_LENGTH;
+ jump->flags |= IS_COND16;
+ break;
+ }
+
+ if (src2 == TMP_ZERO && C_IS_R3(src1)) {
+ inst = C_BEQZ | C_RS1_R3(src1) | BRANCH16_LENGTH;
+ jump->flags |= IS_COND16;
+ break;
+ }
+ }
+
inst = BEQ | RS1(src1) | RS2(src2) | BRANCH_LENGTH;
break;
case SLJIT_LESS:
@@ -2939,23 +3656,25 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_cmp(struct sljit_compiler
case SLJIT_SIG_GREATER:
inst = BGE | RS1(src2) | RS2(src1) | BRANCH_LENGTH;
break;
- case SLJIT_SIG_LESS_EQUAL:
+ default: /* SLJIT_SIG_LESS_EQUAL */
inst = BLT | RS1(src2) | RS2(src1) | BRANCH_LENGTH;
break;
}
- PTR_FAIL_IF(push_inst(compiler, inst));
+ SLJIT_COMPILE_ASSERT((C_BEQZ & 0x2) == 0 && (C_BNEZ & 0x2) == 0, branch16_bit_error);
+ if (RISCV_COMPRESSED_CHECK((inst & 0x2) == 0))
+ PTR_FAIL_IF(push_inst16(compiler, (sljit_u16)inst));
+ else
+ PTR_FAIL_IF(push_inst(compiler, inst));
jump->addr = compiler->size;
- PTR_FAIL_IF(push_inst(compiler, JALR | RD(TMP_ZERO) | RS1(TMP_REG1) | IMM_I(0)));
+ PTR_FAIL_IF(push_inst16(compiler, 0));
/* Maximum number of instructions required for generating a constant. */
compiler->size += JUMP_MAX_SIZE - 1;
return jump;
}
-#undef BRANCH_LENGTH
-
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
{
struct sljit_jump *jump;
@@ -2969,6 +3688,10 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG1, src, srcw));
src = TMP_REG1;
}
+
+ if (RISCV_HAS_COMPRESSED(200))
+ return push_inst16(compiler, ((type >= SLJIT_FAST_CALL) ? C_JALR : C_JR) | C_RD(src));
+
return push_inst(compiler, JALR | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RS1(src) | IMM_I(0));
}
@@ -2979,7 +3702,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compi
jump->u.target = (sljit_uw)srcw;
jump->addr = compiler->size;
- FAIL_IF(push_inst(compiler, JALR | RD((type >= SLJIT_FAST_CALL) ? RETURN_ADDR_REG : TMP_ZERO) | RS1(TMP_REG1) | IMM_I(0)));
+ FAIL_IF(push_inst16(compiler, 0));
/* Maximum number of instructions required for generating a constant. */
compiler->size += JUMP_MAX_SIZE - 1;
@@ -3110,8 +3833,11 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2_reg)
{
- sljit_ins *ptr;
+ sljit_u16 *ptr;
sljit_uw size;
+ sljit_ins ins;
+ sljit_s32 cond_is_1;
+ sljit_s32 is_compare = (type & SLJIT_COMPARE_SELECT);
#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
sljit_ins word = (sljit_ins)(type & SLJIT_32) >> 5;
sljit_s32 inp_flags = ((type & SLJIT_32) ? INT_DATA : WORD_DATA) | LOAD_DATA;
@@ -3126,13 +3852,92 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
ADJUST_LOCAL_OFFSET(src1, src1w);
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ if (src1 == SLJIT_IMM && word)
+ src1w = (sljit_s32)src1w;
+#endif /* SLJIT_CONFIG_RISCV_64 */
+
+ type &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);
+
+ if (is_compare || RISCV_HAS_ICOND(100)) {
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(emit_op_mem(compiler, inp_flags, TMP_REG1, src1, src1w));
+ src1 = TMP_REG1;
+ src1w = 0;
+ } else if (src1 == SLJIT_IMM) {
+ if (src1w == 0) {
+ src1 = TMP_ZERO;
+ } else {
+ FAIL_IF(load_immediate(compiler, TMP_REG1, src1w, TMP_REG3));
+ src1 = TMP_REG1;
+ src1w = 0;
+ }
+ }
+
+ if (RISCV_HAS_BITMANIP_B(93) && is_compare) {
+ switch (type) {
+ case SLJIT_LESS:
+ case SLJIT_LESS_EQUAL:
+ return push_inst(compiler, MINU | RD(dst_reg) | RS1(src1) | RS2(src2_reg));
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_EQUAL:
+ return push_inst(compiler, MAXU | RD(dst_reg) | RS1(src1) | RS2(src2_reg));
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ return push_inst(compiler, MIN | RD(dst_reg) | RS1(src1) | RS2(src2_reg));
+ default:
+ return push_inst(compiler, MAX | RD(dst_reg) | RS1(src1) | RS2(src2_reg));
+ }
+ }
+
+ if (RISCV_HAS_ICOND(100)) {
+ if (is_compare) {
+ cond_is_1 = 0;
+
+ switch (type) {
+ case SLJIT_LESS:
+ case SLJIT_LESS_EQUAL:
+ cond_is_1 = 1;
+ SLJIT_FALLTHROUGH
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_EQUAL:
+ FAIL_IF(push_inst(compiler, SLTU | RD(OTHER_FLAG) | RS1(src1) | RS2(src2_reg)));
+ break;
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ cond_is_1 = 1;
+ SLJIT_FALLTHROUGH
+ default:
+ FAIL_IF(push_inst(compiler, SLT | RD(OTHER_FLAG) | RS1(src1) | RS2(src2_reg)));
+ break;
+ }
+
+ type = OTHER_FLAG;
+ } else {
+ /* BEQ instruction (type is inverted). */
+ cond_is_1 = (get_jump_instruction(type) & F3(0x1)) == 0;
+ type = (type == SLJIT_EQUAL || type == SLJIT_NOT_EQUAL) ? EQUAL_FLAG : OTHER_FLAG;
+ }
+
+ if (src1 == TMP_ZERO)
+ return push_inst(compiler, (cond_is_1 ? CZERO_NEZ : CZERO_EQZ) | RD(dst_reg) | RS1(src2_reg) | RS2(type));
+
+ FAIL_IF(push_inst(compiler, (cond_is_1 ? CZERO_EQZ : CZERO_NEZ) | RD(TMP_REG1) | RS1(src1) | RS2(type)));
+ FAIL_IF(push_inst(compiler, (cond_is_1 ? CZERO_NEZ : CZERO_EQZ) | RD(dst_reg) | RS1(src2_reg) | RS2(type)));
+ return push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));
+ }
+ }
+
if (dst_reg != src2_reg) {
if (dst_reg == src1) {
src1 = src2_reg;
src1w = 0;
- type ^= 0x1;
+ src2_reg = dst_reg;
+ if (!is_compare)
+ type ^= 0x1;
} else {
if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
+ SLJIT_ASSERT(!(type & SLJIT_COMPARE_SELECT));
FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(dst_reg) | IMM_I(0)));
if ((src1 & REG_MASK) == dst_reg)
@@ -3146,25 +3951,77 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
}
}
+ if (src1 == SLJIT_IMM && (src1w <= 0 && src1w >= -1)) {
+ src1 = OTHER_FLAG;
+
+ if (type == SLJIT_EQUAL || type == SLJIT_NOT_EQUAL) {
+ FAIL_IF(push_inst(compiler, SLTUI | RD(TMP_REG1) | RS1(EQUAL_FLAG) | IMM_I(1)));
+ src1 = TMP_REG1;
+ cond_is_1 = (type == SLJIT_EQUAL);
+ } else {
+ /* BEQ instruction (type is inverted). */
+ cond_is_1 = (get_jump_instruction(type) & F3(0x1)) == 0;
+ }
+
+ if (src1w == 0) {
+ if (cond_is_1)
+ FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src1) | IMM_I(-1)));
+ else
+ FAIL_IF(push_inst(compiler, SUB | RD(TMP_REG1) | RS1(TMP_ZERO) | RS2(src1)));
+
+ return push_inst(compiler, AND | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));
+ }
+
+ if (cond_is_1)
+ FAIL_IF(push_inst(compiler, SUB | RD(TMP_REG1) | RS1(TMP_ZERO) | RS2(src1)));
+ else
+ FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(src1) | IMM_I(-1)));
+
+ return push_inst(compiler, OR | RD(dst_reg) | RS1(dst_reg) | RS2(TMP_REG1));
+ }
+
size = compiler->size;
- ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ ptr = (sljit_u16 *)ensure_buf(compiler, sizeof(sljit_ins));
FAIL_IF(!ptr);
- compiler->size++;
+ compiler->size += 2;
if (src1 & SLJIT_MEM) {
FAIL_IF(emit_op_mem(compiler, inp_flags, dst_reg, src1, src1w));
} else if (src1 == SLJIT_IMM) {
-#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
- if (word)
- src1w = (sljit_s32)src1w;
-#endif /* SLJIT_CONFIG_RISCV_64 */
FAIL_IF(load_immediate(compiler, dst_reg, src1w, TMP_REG1));
} else
FAIL_IF(push_inst(compiler, ADDI | WORD | RD(dst_reg) | RS1(src1) | IMM_I(0)));
size = compiler->size - size;
- *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((size & 0x7) << 9) | (sljit_ins)((size >> 3) << 25);
+
+ if (is_compare) {
+ switch (type) {
+ case SLJIT_LESS:
+ case SLJIT_LESS_EQUAL:
+ ins = BGEU;
+ break;
+ case SLJIT_GREATER:
+ case SLJIT_GREATER_EQUAL:
+ ins = BLTU;
+ break;
+ case SLJIT_SIG_LESS:
+ case SLJIT_SIG_LESS_EQUAL:
+ ins = BGE;
+ break;
+ default:
+ ins = BLT;
+ break;
+ }
+
+ ins |= RS1(src1) | RS2(src2_reg);
+ } else {
+ ins = get_jump_instruction(type);
+ }
+
+ ins |= (sljit_ins)((size & 0xf) << 8) | (sljit_ins)((size >> 4) << 25);
+ ptr[0] = (sljit_u16)ins;
+ ptr[1] = (sljit_u16)(ins >> 16);
return SLJIT_SUCCESS;
}
@@ -3175,7 +4032,8 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2_freg)
{
- sljit_ins *ptr;
+ sljit_u16 *ptr;
+ sljit_ins ins;
sljit_uw size;
CHECK_ERROR();
@@ -3194,9 +4052,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
size = compiler->size;
- ptr = (sljit_ins*)ensure_buf(compiler, sizeof(sljit_ins));
+ ptr = (sljit_u16 *)ensure_buf(compiler, sizeof(sljit_ins));
FAIL_IF(!ptr);
- compiler->size++;
+ compiler->size += 2;
if (src1 & SLJIT_MEM)
FAIL_IF(emit_op_mem(compiler, FLOAT_DATA(type) | LOAD_DATA, dst_freg, src1, src1w));
@@ -3204,7 +4062,9 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fselect(struct sljit_compiler *com
FAIL_IF(push_inst(compiler, FSGNJ_S | FMT(type) | FRD(dst_freg) | FRS1(src1) | FRS2(src1)));
size = compiler->size - size;
- *ptr = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((size & 0x7) << 9) | (sljit_ins)((size >> 3) << 25);
+ ins = get_jump_instruction(type & ~SLJIT_32) | (sljit_ins)((size & 0xf) << 8) | (sljit_ins)((size >> 4) << 25);
+ ptr[0] = (sljit_u16)ins;
+ ptr[1] = (sljit_u16)(ins >> 16);
return SLJIT_SUCCESS;
}
@@ -3276,7 +4136,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_load(struct sljit_compiler
CHECK_ERROR();
CHECK(check_sljit_emit_atomic_load(compiler, op, dst_reg, mem_reg));
- if (op & SLJIT_ATOMIC_USE_CAS)
+ if (!RISCV_HAS_ATOMIC(200) || (op & SLJIT_ATOMIC_USE_CAS))
return SLJIT_ERR_UNSUPPORTED;
switch (GET_OPCODE(op)) {
@@ -3314,7 +4174,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
CHECK_ERROR();
CHECK(check_sljit_emit_atomic_store(compiler, op, src_reg, mem_reg, temp_reg));
- if (op & SLJIT_ATOMIC_USE_CAS)
+ if (!RISCV_HAS_ATOMIC(200) || (op & SLJIT_ATOMIC_USE_CAS))
return SLJIT_ERR_UNSUPPORTED;
switch (GET_OPCODE(op)) {
@@ -3339,6 +4199,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
return push_inst(compiler, ins | RD(OTHER_FLAG) | RS1(mem_reg) | RS2(src_reg));
}
+static sljit_s32 sljit_max_vector_length = 0;
+
+static void init_compiler(void)
+{
+ sljit_sw vector_length;
+ sljit_s32 vector_length_log2;
+
+ if (!RISCV_HAS_VECTOR(100))
+ return;
+
+ __asm__ __volatile__ ("csrr %0, 0xc22" : "=r" (vector_length));
+
+ /* Probably something is wrong. */
+ if (vector_length < (1 << 3))
+ return;
+
+ vector_length_log2 = 3;
+ if (vector_length_log2 < 6 && vector_length > (1 << vector_length_log2))
+ vector_length_log2++;
+ sljit_max_vector_length = vector_length_log2;
+}
+
/*
SEW = Selected element width
LMUL = Vector register group multiplier
@@ -3359,13 +4241,22 @@ static SLJIT_INLINE sljit_s32 sljit_emit_vsetivli(struct sljit_compiler *compile
sljit_ins elem_size = (sljit_ins)SLJIT_SIMD_GET_ELEM_SIZE(type);
sljit_ins avl = (sljit_ins)1 << (SLJIT_SIMD_GET_REG_SIZE(type) - elem_size);
- return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | (elem_size << 23) | (vlmul << 20) | (avl << 15));
+ if (avl < 31)
+ return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | (elem_size << 23) | (vlmul << 20) | (avl << 15));
+
+ FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(avl)));
+ return push_inst(compiler, VSETVLI | RD(TMP_REG1) | (elem_size << 23) | (vlmul << 20) | RS1(TMP_REG1));
}
static SLJIT_INLINE sljit_s32 sljit_emit_vsetivli_size(struct sljit_compiler *compiler, sljit_s32 reg_size, sljit_s32 elem_size)
{
sljit_ins avl = (sljit_ins)1 << (reg_size - elem_size);
- return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (avl << 15));
+
+ if (avl < 31)
+ return push_inst(compiler, VSETIVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | (avl << 15));
+
+ FAIL_IF(push_inst(compiler, ADDI | RD(TMP_REG1) | RS1(TMP_ZERO) | IMM_I(avl)));
+ return push_inst(compiler, VSETVLI | RD(TMP_REG1) | ((sljit_ins)elem_size << 23) | RS1(TMP_REG1));
}
static sljit_s32 sljit_emit_vmem(struct sljit_compiler *compiler, sljit_ins ins, sljit_s32 elem_size, sljit_s32 mem, sljit_sw memw)
@@ -3415,7 +4306,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_mov(struct sljit_compiler *co
ADJUST_LOCAL_OFFSET(srcdst, srcdstw);
- if (reg_size != 4)
+ if (reg_size < 3 || reg_size > sljit_max_vector_length)
return SLJIT_ERR_UNSUPPORTED;
if (type & SLJIT_SIMD_TEST)
@@ -3484,7 +4375,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
ADJUST_LOCAL_OFFSET(src, srcw);
- if (reg_size != 4)
+ if (reg_size < 3 || reg_size > sljit_max_vector_length)
return SLJIT_ERR_UNSUPPORTED;
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
@@ -3542,7 +4433,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_mov(struct sljit_compile
ADJUST_LOCAL_OFFSET(srcdst, srcdstw);
- if (reg_size != 4)
+ if (reg_size < 3 || reg_size > sljit_max_vector_length)
return SLJIT_ERR_UNSUPPORTED;
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
@@ -3645,7 +4536,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
CHECK_ERROR();
CHECK(check_sljit_emit_simd_lane_replicate(compiler, type, vreg, src, src_lane_index));
- if (reg_size != 4)
+ if (reg_size < 3 || reg_size > sljit_max_vector_length)
return SLJIT_ERR_UNSUPPORTED;
if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3)
@@ -3676,7 +4567,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_extend(struct sljit_compiler
ADJUST_LOCAL_OFFSET(src, srcw);
- if (reg_size != 4)
+ if (reg_size < 3 || reg_size > sljit_max_vector_length)
return SLJIT_ERR_UNSUPPORTED;
#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
@@ -3741,7 +4632,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c
ADJUST_LOCAL_OFFSET(dst, dstw);
- if (reg_size != 4)
+ if (reg_size < 3 || reg_size > sljit_max_vector_length)
return SLJIT_ERR_UNSUPPORTED;
if (((type & SLJIT_SIMD_FLOAT) && elem_size < 2) || elem_size > 3)
@@ -3749,7 +4640,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_sign(struct sljit_compiler *c
FAIL_IF(sljit_emit_vsetivli(compiler, type, 0));
FAIL_IF(push_inst(compiler, VMV_VI | VRD(TMP_VREG1) | (0x0 << 15)));
- FAIL_IF(push_inst(compiler, VMSLE_VI | VRD(TMP_VREG1) | (0x0 << 15) | VRS2(vreg)));
+ FAIL_IF(push_inst(compiler, VMSLE_VI | VRD(TMP_VREG1) | (0x1f << 15) | VRS2(vreg)));
FAIL_IF(sljit_emit_vsetivli_size(compiler, 2, 2));
FAIL_IF(push_inst(compiler, VMV_XS | RD(dst_r) | VRS2(TMP_VREG1)));
@@ -3771,7 +4662,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co
ADJUST_LOCAL_OFFSET(src2, src2w);
- if (reg_size != 4)
+ if (reg_size < 3 || reg_size > sljit_max_vector_length)
return SLJIT_ERR_UNSUPPORTED;
if ((type & SLJIT_SIMD_FLOAT) && (elem_size < 2 || elem_size > 3))
@@ -3822,13 +4713,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_op2(struct sljit_compiler *co
return push_inst(compiler, ins | VRD(dst_vreg) | VRS1(src2) | VRS2(src1_vreg));
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
struct sljit_const *const_;
sljit_s32 dst_r;
+ sljit_s32 mem_flags = WORD_DATA;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
@@ -3836,34 +4730,77 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compi
set_const(const_, compiler);
dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(emit_const(compiler, dst_r, init_value, ADDI | RD(dst_r)));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ if (init_value & 0x100)
+ init_value |= 0xf00;
+ else
+ init_value &= 0xff;
+
+ PTR_FAIL_IF(push_inst(compiler, ADDI | RD(dst_r) | IMM_I(init_value)));
+ mem_flags = BYTE_DATA;
+ break;
+
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ case SLJIT_MOV32:
+ mem_flags = INT_DATA;
+ SLJIT_FALLTHROUGH
+ case SLJIT_MOV_S32:
+ if ((init_value & 0x800) != 0)
+ init_value ^= ~(sljit_sw)0xfff;
+
+ PTR_FAIL_IF(push_inst(compiler, LUI | RD(dst_r) | (sljit_ins)(init_value & ~(sljit_sw)0xfff)));
+ PTR_FAIL_IF(push_inst(compiler, XORI | RD(dst_r) | RS1(dst_r) | IMM_I(init_value)));
+ break;
+#endif /* SLJIT_CONFIG_RISCV_64 */
+
+ default:
+ PTR_FAIL_IF(emit_const(compiler, dst_r, init_value, ADDI | RD(dst_r)));
+ break;
+ }
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
+ PTR_FAIL_IF(emit_op_mem(compiler, mem_flags, TMP_REG2, dst, dstw));
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_s32 dst_r;
+ sljit_s32 dst_r, target_r;
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
+
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = TMP_REG1;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA | LOAD_DATA, TMP_REG2, dst, dstw));
+ }
+
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF(!jump);
set_mov_addr(jump, compiler, 0);
- dst_r = FAST_IS_REG(dst) ? dst : TMP_REG2;
- PTR_FAIL_IF(push_inst(compiler, (sljit_ins)dst_r));
-#if (defined SLJIT_CONFIG_RISCV_32 && SLJIT_CONFIG_RISCV_32)
- compiler->size += 1;
-#else /* !SLJIT_CONFIG_RISCV_32 */
- compiler->size += 5;
-#endif /* SLJIT_CONFIG_RISCV_32 */
+ PTR_FAIL_IF(push_inst16(compiler, (sljit_u16)target_r));
+ compiler->size += JUMP_MAX_SIZE - 1;
+
+ if (op == SLJIT_ADD_ABS_ADDR) {
+ if (RISCV_HAS_COMPRESSED(200))
+ PTR_FAIL_IF(push_inst16(compiler, C_ADD | C_RD(dst_r) | C_RS2(TMP_REG1)));
+ else
+ PTR_FAIL_IF(push_inst(compiler, ADD | RD(dst_r) | RS1(dst_r) | RS2(TMP_REG1)));
+ }
if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_op_mem(compiler, WORD_DATA, TMP_REG2, dst, dstw));
@@ -3871,7 +4808,48 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_com
return jump;
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ sljit_u16 *inst;
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ inst = (sljit_u16*)addr;
+ SLJIT_ASSERT((inst[0] & 0x707f) == ADDI);
+
+ if (new_constant & 0x100)
+ new_constant |= 0xf00;
+ else
+ new_constant &= 0xff;
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ inst[1] = (sljit_u16)(new_constant << 4) | (inst[1] & 0xf);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
+ inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ return;
+
+#if (defined SLJIT_CONFIG_RISCV_64 && SLJIT_CONFIG_RISCV_64)
+ case SLJIT_MOV32:
+ case SLJIT_MOV_S32:
+ inst = (sljit_u16*)addr;
+ SLJIT_ASSERT((inst[0] & 0x7f) == LUI && (inst[2] & 0x707f) == XORI);
+
+ if ((new_constant & 0x800) != 0)
+ new_constant ^= ~(sljit_sw)0xfff;
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 0);
+ inst[0] = (sljit_u16)((inst[0] & 0xfff) | (new_constant & 0xf000));
+ inst[1] = (sljit_u16)(new_constant >> 16);
+ inst[3] = (sljit_u16)(new_constant << 4) | (inst[3] & 0xf);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 4, 1);
+ inst = (sljit_u16 *)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 4);
+ return;
+#endif /* SLJIT_CONFIG_RISCV_64 */
+
+ default:
+ sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ return;
+ }
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeS390X.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeS390X.c
index 7ce9f9fcdcc..98f671e1027 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeS390X.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeS390X.c
@@ -93,9 +93,6 @@ static const sljit_gpr r15 = 15; /* reg_map[SLJIT_NUMBER_OF_REGISTERS + 1]: stac
#define tmp0 r0
#define tmp1 r1
-/* When reg cannot be unused. */
-#define IS_GPR_REG(reg) ((reg > 0) && (reg) <= SLJIT_SP)
-
/* Link register. */
static const sljit_gpr link_r = 14; /* r14 */
@@ -125,11 +122,6 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2] = {
#define F32(r) (R32A((sljit_ins)freg_map[r]))
#define F36(r) (R36A((sljit_ins)freg_map[r]))
-struct sljit_s390x_const {
- struct sljit_const const_; /* must be first */
- sljit_sw init_value; /* required to build literal pool */
-};
-
/* Convert SLJIT register to hardware register. */
static SLJIT_INLINE sljit_gpr gpr(sljit_s32 r)
{
@@ -169,14 +161,14 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t
switch (type) {
case SLJIT_EQUAL:
if (SLJIT_ADD_SUB_NO_COMPARE(compiler->status_flags_state)) {
- sljit_s32 type = GET_FLAG_TYPE(compiler->status_flags_state);
- if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL)
+ sljit_s32 flag_type = GET_FLAG_TYPE(compiler->status_flags_state);
+ if (flag_type >= SLJIT_SIG_LESS && flag_type <= SLJIT_SIG_LESS_EQUAL)
return cc0;
- if (type == SLJIT_OVERFLOW)
+ if (flag_type == SLJIT_OVERFLOW)
return (cc0 | cc3);
return (cc0 | cc2);
}
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ATOMIC_STORED:
case SLJIT_F_EQUAL:
@@ -185,14 +177,14 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t
case SLJIT_NOT_EQUAL:
if (SLJIT_ADD_SUB_NO_COMPARE(compiler->status_flags_state)) {
- sljit_s32 type = GET_FLAG_TYPE(compiler->status_flags_state);
- if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL)
+ sljit_s32 flag_type = GET_FLAG_TYPE(compiler->status_flags_state);
+ if (flag_type >= SLJIT_SIG_LESS && flag_type <= SLJIT_SIG_LESS_EQUAL)
return (cc1 | cc2 | cc3);
- if (type == SLJIT_OVERFLOW)
+ if (flag_type == SLJIT_OVERFLOW)
return (cc1 | cc2);
return (cc1 | cc3);
}
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_UNORDERED_OR_NOT_EQUAL:
return (cc1 | cc2 | cc3);
@@ -223,7 +215,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t
case SLJIT_NOT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
return (cc2 | cc3);
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_SIG_LESS_EQUAL:
case SLJIT_F_LESS_EQUAL:
@@ -233,7 +225,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t
case SLJIT_CARRY:
if (compiler->status_flags_state & SLJIT_CURRENT_FLAGS_SUB)
return (cc0 | cc1);
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_SIG_GREATER:
case SLJIT_UNORDERED_OR_GREATER:
@@ -246,7 +238,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t
case SLJIT_OVERFLOW:
if (compiler->status_flags_state & SLJIT_SET_Z)
return (cc2 | cc3);
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_UNORDERED:
return cc3;
@@ -254,7 +246,7 @@ static SLJIT_INLINE sljit_u8 get_cc(struct sljit_compiler *compiler, sljit_s32 t
case SLJIT_NOT_OVERFLOW:
if (compiler->status_flags_state & SLJIT_SET_Z)
return (cc0 | cc1);
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_ORDERED:
return (cc0 | cc1 | cc2);
@@ -333,7 +325,7 @@ static SLJIT_INLINE int have_facility_static(facility_bit x)
return 0;
}
-static SLJIT_INLINE unsigned long get_hwcap()
+static SLJIT_INLINE unsigned long get_hwcap(void)
{
static unsigned long hwcap = 0;
if (SLJIT_UNLIKELY(!hwcap)) {
@@ -343,7 +335,7 @@ static SLJIT_INLINE unsigned long get_hwcap()
return hwcap;
}
-static SLJIT_INLINE int have_stfle()
+static SLJIT_INLINE int have_stfle(void)
{
if (have_facility_static(STORE_FACILITY_LIST_EXTENDED_FACILITY))
return 1;
@@ -410,10 +402,10 @@ HAVE_FACILITY(have_misc2, MISCELLANEOUS_INSTRUCTION_EXTENSIONS_2_FACILITY)
#define CHECK_SIGNED(v, bitlen) \
((v) >= -(1 << ((bitlen) - 1)) && (v) < (1 << ((bitlen) - 1)))
-#define is_s8(d) CHECK_SIGNED((d), 8)
-#define is_s16(d) CHECK_SIGNED((d), 16)
+#define is_s8(d) ((sljit_sw)(d) == (sljit_s8)(d))
+#define is_s16(d) ((sljit_sw)(d) == (sljit_s16)(d))
#define is_s20(d) CHECK_SIGNED((d), 20)
-#define is_s32(d) ((d) == (sljit_s32)(d))
+#define is_s32(d) ((sljit_sw)(d) == (sljit_s32)(d))
static SLJIT_INLINE sljit_ins disp_s20(sljit_s32 d)
{
@@ -983,6 +975,12 @@ static const sljit_ins store_forms[3] = {
0xe30000000024 /* stg */
};
+static const sljit_ins store_byte_forms[3] = {
+ 0x42000000 /* stc */,
+ 0xe30000000072 /* stcy */,
+ 0
+};
+
static const sljit_ins load_halfword_forms[3] = {
0x48000000 /* lh */,
0xe30000000078 /* lhy */,
@@ -1021,6 +1019,13 @@ static SLJIT_INLINE sljit_s32 store_word(struct sljit_compiler *compiler, sljit_
return load_store_op(compiler, src_r, dst, dstw, is_32bit, store_forms);
}
+/* May clobber tmp1. */
+static SLJIT_INLINE sljit_s32 store_byte(struct sljit_compiler *compiler, sljit_gpr src_r,
+ sljit_s32 dst, sljit_sw dstw)
+{
+ return load_store_op(compiler, src_r, dst, dstw, 1, store_byte_forms);
+}
+
#undef WHEN
static sljit_s32 emit_move(struct sljit_compiler *compiler,
@@ -1029,7 +1034,7 @@ static sljit_s32 emit_move(struct sljit_compiler *compiler,
{
sljit_gpr src_r;
- SLJIT_ASSERT(!IS_GPR_REG(src) || dst_r != gpr(src & REG_MASK));
+ SLJIT_ASSERT(!FAST_IS_REG(src) || dst_r != gpr(src & REG_MASK));
if (src == SLJIT_IMM)
return push_load_imm_inst(compiler, dst_r, srcw);
@@ -1392,6 +1397,12 @@ static sljit_s32 emit_non_commutative(struct sljit_compiler *compiler, const str
return emit_rrf(compiler, ins, dst, src1, src1w, src2, src2w);
}
+static SLJIT_INLINE sljit_u16 *process_extended_label(sljit_u16 *code_ptr, struct sljit_extended_label *ext_label)
+{
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ return (sljit_u16*)((sljit_uw)code_ptr & ~(ext_label->data));
+}
+
SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compiler, sljit_s32 options, void *exec_allocator_data)
{
struct sljit_label *label;
@@ -1413,30 +1424,28 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
sljit_sw source, offset;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reverse_buf(compiler);
jump = compiler->jumps;
while (jump != NULL) {
- if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR | JUMP_MOV_ADDR)) {
+ if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR)) {
/* encoded: */
/* brasl %r14, <rel_addr> (or brcl <mask>, <rel_addr>) */
/* replace with: */
/* lgrl %r1, <pool_addr> */
/* bras %r14, %r1 (or bcr <mask>, %r1) */
- pool_size += sizeof(*pool);
+ if (((jump->flags & SLJIT_REWRITABLE_JUMP) || !is_s32(jump->u.target)))
+ pool_size += sizeof(sljit_uw);
+ else
+ jump->flags |= PATCH_IMM32;
+
if (!(jump->flags & JUMP_MOV_ADDR))
ins_size += 2;
}
jump = jump->next;
}
- const_ = compiler->consts;
- while (const_) {
- pool_size += sizeof(*pool);
- const_ = const_->next;
- }
-
/* pad code size to 8 bytes so is accessible with half word offsets */
/* the literal pool needs to be doubleword aligned */
pad_size = ((ins_size + 7UL) & ~7UL) - ins_size;
@@ -1475,80 +1484,91 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!const_ || const_->addr >= half_count);
if (next_min_addr == next_label_size) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label = label->next;
next_label_size = SLJIT_GET_NEXT_SIZE(label);
}
if (next_min_addr == next_jump_addr) {
- if (SLJIT_UNLIKELY(jump->flags & JUMP_MOV_ADDR)) {
- source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
-
- jump->addr = (sljit_uw)pool_ptr;
-
- /* store target into pool */
- offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
- pool_ptr++;
+ jump->addr = (sljit_uw)code_ptr;
- SLJIT_ASSERT(!(offset & 1));
- offset >>= 1;
- SLJIT_ASSERT(is_s32(offset));
- ins |= (sljit_ins)offset & 0xffffffff;
+ if (SLJIT_UNLIKELY(jump->flags & JUMP_MOV_ADDR)) {
+ if (jump->flags & PATCH_IMM32) {
+ SLJIT_ASSERT((jump->flags & JUMP_ADDR) && is_s32(jump->u.target));
+ ins = 0xc00100000000 /* lgfi */ | (ins & 0xf000000000);
+ } else if (jump->flags & JUMP_ADDR) {
+ source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
+ offset = (sljit_sw)(jump->u.target - (sljit_uw)source);
+
+ if ((offset & 0x1) != 0 || offset > 0xffffffffl || offset < -0x100000000l) {
+ jump->addr = (sljit_uw)pool_ptr;
+ jump->flags |= PATCH_POOL;
+
+ /* store target into pool */
+ offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+ pool_ptr++;
+
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1;
+ SLJIT_ASSERT(is_s32(offset));
+ ins = 0xc40800000000 /* lgrl */ | (ins & 0xf000000000) | (sljit_ins)(offset & 0xffffffff);
+ }
+ }
} else if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR)) {
- sljit_ins arg;
-
- jump->addr = (sljit_uw)pool_ptr;
-
- /* load address into tmp1 */
source = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
-
- SLJIT_ASSERT(!(offset & 1));
- offset >>= 1;
- SLJIT_ASSERT(is_s32(offset));
-
- code_ptr[0] = (sljit_u16)(0xc408 | R4A(tmp1) /* lgrl */);
- code_ptr[1] = (sljit_u16)(offset >> 16);
- code_ptr[2] = (sljit_u16)offset;
- code_ptr += 3;
- pool_ptr++;
-
- /* branch to tmp1 */
- arg = (ins >> 36) & 0xf;
- if (((ins >> 32) & 0xf) == 4) {
- /* brcl -> bcr */
- ins = bcr(arg, tmp1);
- } else {
- SLJIT_ASSERT(((ins >> 32) & 0xf) == 5);
- /* brasl -> basr */
- ins = basr(arg, tmp1);
+
+ if (jump->flags & PATCH_IMM32) {
+ SLJIT_ASSERT((jump->flags & JUMP_ADDR) && is_s32(jump->u.target));
+ code_ptr[0] = (sljit_u16)(0xc001 /* lgfi */ | R4A(tmp1));
+ code_ptr += 3;
+ } else if (!(jump->flags & SLJIT_REWRITABLE_JUMP)) {
+ offset = (sljit_sw)(jump->u.target - (sljit_uw)source);
+
+ if ((offset & 0x1) != 0 || offset > 0xffffffffl || offset < -0x100000000l)
+ jump->flags |= PATCH_POOL;
+ } else
+ jump->flags |= PATCH_POOL;
+
+ if (jump->flags & PATCH_POOL) {
+ jump->addr = (sljit_uw)pool_ptr;
+
+ /* load address into tmp1 */
+ offset = (sljit_sw)SLJIT_ADD_EXEC_OFFSET(pool_ptr, executable_offset) - source;
+
+ SLJIT_ASSERT(!(offset & 1));
+ offset >>= 1;
+ SLJIT_ASSERT(is_s32(offset));
+
+ code_ptr[0] = (sljit_u16)(0xc408 /* lgrl */ | R4A(tmp1));
+ code_ptr[1] = (sljit_u16)(offset >> 16);
+ code_ptr[2] = (sljit_u16)offset;
+ code_ptr += 3;
+ pool_ptr++;
}
- /* Adjust half_count. */
- half_count += 2;
- } else
- jump->addr = (sljit_uw)code_ptr;
+ if (jump->flags & (PATCH_POOL | PATCH_IMM32)) {
+ /* branch to tmp1 */
+ if (((ins >> 32) & 0xf) == 4) {
+ /* brcl -> bcr */
+ ins = 0x0700 /* bcr */ | ((ins >> 32) & 0xf0) | R0A(tmp1);
+ } else {
+ SLJIT_ASSERT(((ins >> 32) & 0xf) == 5);
+ /* brasl -> basr */
+ ins = 0x0d00 /* basr */ | ((ins >> 32) & 0xf0) | R0A(tmp1);
+ }
+
+ /* Adjust half_count. */
+ half_count += 2;
+ }
+ }
jump = jump->next;
next_jump_addr = SLJIT_GET_NEXT_ADDRESS(jump);
- } else if (next_min_addr == next_const_addr) {
- /* update instruction with relative address of constant */
- source = (sljit_sw)code_ptr;
- offset = (sljit_sw)pool_ptr - source;
-
- SLJIT_ASSERT(!(offset & 0x1));
- offset >>= 1; /* halfword (not byte) offset */
- SLJIT_ASSERT(is_s32(offset));
-
- ins |= (sljit_ins)offset & 0xffffffff;
-
- /* update address */
- const_->addr = (sljit_uw)pool_ptr;
-
- /* store initial value into pool and update pool address */
- *(pool_ptr++) = (sljit_uw)(((struct sljit_s390x_const*)const_)->init_value);
-
- /* move to next constant */
+ } else if (next_min_addr == next_const_addr) {
+ const_->addr = (sljit_uw)code_ptr;
const_ = const_->next;
next_const_addr = SLJIT_GET_NEXT_ADDRESS(const_);
}
@@ -1574,6 +1594,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} while (buf);
if (next_label_size == half_count) {
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label = label->next;
}
@@ -1581,27 +1604,32 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
SLJIT_ASSERT(!label);
SLJIT_ASSERT(!jump);
SLJIT_ASSERT(!const_);
- SLJIT_ASSERT(code + (ins_size >> 1) == code_ptr);
- SLJIT_ASSERT((sljit_u8 *)pool + pool_size == (sljit_u8 *)pool_ptr);
+ SLJIT_ASSERT(code_ptr <= code + (ins_size >> 1));
+ SLJIT_ASSERT((sljit_u8 *)pool_ptr <= (sljit_u8 *)pool + pool_size);
jump = compiler->jumps;
while (jump != NULL) {
offset = (sljit_sw)((jump->flags & JUMP_ADDR) ? jump->u.target : jump->u.label->u.addr);
- if (jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR | JUMP_MOV_ADDR)) {
- /* Store jump target into pool. */
- *(sljit_uw*)(jump->addr) = (sljit_uw)offset;
- } else {
+ if (!(jump->flags & (PATCH_POOL | PATCH_IMM32))) {
code_ptr = (sljit_u16*)jump->addr;
offset -= (sljit_sw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
- /* offset must be halfword aligned */
+ /* Offset must be halfword aligned. */
SLJIT_ASSERT(!(offset & 1));
offset >>= 1;
SLJIT_ASSERT(is_s32(offset)); /* TODO(mundaym): handle arbitrary offsets */
code_ptr[1] = (sljit_u16)(offset >> 16);
code_ptr[2] = (sljit_u16)offset;
+ } else if (jump->flags & PATCH_POOL) {
+ /* Store jump target into pool. */
+ *(sljit_uw*)(jump->addr) = (sljit_uw)offset;
+ } else {
+ SLJIT_ASSERT(is_s32(offset));
+ code_ptr = (sljit_u16*)jump->addr;
+ code_ptr[1] = (sljit_u16)(offset >> 16);
+ code_ptr[2] = (sljit_u16)offset;
}
jump = jump->next;
}
@@ -2243,7 +2271,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
}
/* STORE and STORE IMMEDIATE */
if ((dst & SLJIT_MEM) && (FAST_IS_REG(src) || src == SLJIT_IMM)) {
- struct addr mem;
sljit_gpr reg = FAST_IS_REG(src) ? gpr(src) : tmp0;
if (src == SLJIT_IMM) {
@@ -2276,7 +2303,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
#undef LEVAL
/* MOVE CHARACTERS */
if ((dst & SLJIT_MEM) && (src & SLJIT_MEM)) {
- struct addr mem;
FAIL_IF(make_addr_bxy(compiler, &mem, src, srcw, tmp1));
switch (opcode) {
case SLJIT_MOV_U8:
@@ -2335,7 +2361,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op1(struct sljit_compiler *compile
case SLJIT_REV_U32:
case SLJIT_REV_S32:
op |= SLJIT_32;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_REV:
case SLJIT_REV_U16:
case SLJIT_REV_S16:
@@ -2648,7 +2674,7 @@ static sljit_s32 sljit_emit_bitwise_imm(struct sljit_compiler *compiler, sljit_s
sljit_gpr dst_r = tmp0;
sljit_s32 needs_move = 1;
- if (IS_GPR_REG(dst)) {
+ if (FAST_IS_REG(dst)) {
dst_r = gpr(dst & REG_MASK);
if (dst == src1)
needs_move = 0;
@@ -3119,6 +3145,75 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return push_inst(compiler, 0xb9810000 /* ogr */ | R4A(dst_r) | R0A(tmp0));
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_gpr dst_r, tmp_r, src_r;
+ struct addr addr;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= 0x3f;
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ tmp_r = FAST_IS_REG(dst) && (dst != src1) ? gpr(dst) : tmp0;
+
+ if (src2 & SLJIT_MEM) {
+ FAIL_IF(load_word(compiler, tmp_r, src2, src2w, 0 /* 64-bit */));
+ src_r = tmp_r;
+ } else {
+ src_r = gpr(src2);
+ }
+
+ FAIL_IF(push_inst(compiler, 0xeb000000000d /* sllg */ | R36A(tmp_r) | R32A(src_r) | ((sljit_ins)shift_arg << 16)));
+
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(make_addr_bxy(compiler, &addr, src1, src1w, tmp1));
+ FAIL_IF(push_inst(compiler, 0xe30000000008 /* ag */ | R36A(tmp_r) | R32A(addr.index) | R28A(addr.base) | disp_s20(addr.offset)));
+ src_r = tmp_r;
+ } else if (src1 == SLJIT_IMM) {
+ if (is_s32(src1w)) {
+ FAIL_IF(push_inst(compiler, 0xc20800000000 /* agfi */ | R36A(tmp_r) | (sljit_u32)src1w));
+ src_r = tmp_r;
+ } else {
+ src_r = tmp_r != tmp0 ? tmp0 : tmp1;
+ FAIL_IF(push_load_imm_inst(compiler, src_r, src1w));
+ }
+ } else {
+ src_r = gpr(src1);
+ }
+
+ dst_r = (FAST_IS_REG(dst) ? gpr(dst) : tmp0);
+
+ if (src_r != tmp_r) {
+ if (src_r == dst_r) {
+ FAIL_IF(push_inst(compiler, 0xb9080000 /* agr */ | R4A(dst_r) | R0A(tmp_r)));
+ } else {
+ FAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(tmp_r) | R4A(dst_r) | R0A(src_r)));
+ }
+ }
+
+ if (dst & SLJIT_MEM)
+ return store_word(compiler, dst_r, dst, dstw, 0 /* 64-bit */);
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -3131,11 +3226,14 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_RETURN:
- src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
- if (src & SLJIT_MEM)
- FAIL_IF(load_word(compiler, tmp1, src, srcw, 0));
+ if (FAST_IS_REG(src)) {
+ src_r = gpr(src);
+ if (src_r != link_r)
+ FAIL_IF(push_inst(compiler, lgr(link_r, src_r)));
+ } else
+ FAIL_IF(load_word(compiler, link_r, src, srcw, 0));
- return push_inst(compiler, br(src_r));
+ return push_inst(compiler, br(link_r));
case SLJIT_SKIP_FRAMES_BEFORE_FAST_RETURN:
return SLJIT_SUCCESS;
case SLJIT_PREFETCH_L1:
@@ -3163,8 +3261,13 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_dst(struct sljit_compiler *comp
switch (op) {
case SLJIT_FAST_ENTER:
- if (FAST_IS_REG(dst))
- return push_inst(compiler, lgr(gpr(dst), link_r));
+ if (FAST_IS_REG(dst)) {
+ dst_r = gpr(dst);
+
+ if (dst_r == link_r)
+ return SLJIT_SUCCESS;
+ return push_inst(compiler, lgr(dst_r, link_r));
+ }
break;
case SLJIT_GET_RETURN_ADDRESS:
dst_r = FAST_IS_REG(dst) ? gpr(dst) : tmp0;
@@ -3591,6 +3694,60 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, i;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (alignment <= SLJIT_LABEL_ALIGN_2) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - sizeof(sljit_u16);
+
+ for (i = (mask >> 1); i != 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, 0x0700 /* 2-byte nop */));
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+
+ for (i = (buffers->size + 1) >> 1; i > 0; i--)
+ PTR_FAIL_IF(push_inst(compiler, 0x0700 /* 2-byte nop */));
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
{
struct sljit_jump *jump;
@@ -3633,25 +3790,36 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_call(struct sljit_compile
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_ijump(struct sljit_compiler *compiler, sljit_s32 type, sljit_s32 src, sljit_sw srcw)
{
+ struct sljit_jump *jump;
sljit_gpr src_r = FAST_IS_REG(src) ? gpr(src) : tmp1;
CHECK_ERROR();
CHECK(check_sljit_emit_ijump(compiler, type, src, srcw));
- if (src == SLJIT_IMM) {
- SLJIT_ASSERT(!(srcw & 1)); /* target address must be even */
- FAIL_IF(push_load_imm_inst(compiler, src_r, srcw));
- }
- else if (src & SLJIT_MEM) {
- ADJUST_LOCAL_OFFSET(src, srcw);
- FAIL_IF(load_word(compiler, src_r, src, srcw, 0 /* 64-bit */));
+ if (src != SLJIT_IMM) {
+ if (src & SLJIT_MEM) {
+ ADJUST_LOCAL_OFFSET(src, srcw);
+ FAIL_IF(load_word(compiler, src_r, src, srcw, 0 /* 64-bit */));
+ }
+
+ /* emit jump instruction */
+ if (type >= SLJIT_FAST_CALL)
+ return push_inst(compiler, basr(link_r, src_r));
+
+ return push_inst(compiler, br(src_r));
}
- /* emit jump instruction */
+ jump = (struct sljit_jump *)ensure_abuf(compiler, sizeof(struct sljit_jump));
+ FAIL_IF(!jump);
+ set_jump(jump, compiler, JUMP_ADDR);
+ jump->addr = compiler->size;
+ jump->u.target = (sljit_uw)srcw;
+
+ type &= 0xff;
if (type >= SLJIT_FAST_CALL)
- return push_inst(compiler, basr(link_r, src_r));
+ return push_inst(compiler, brasl(link_r, 0));
- return push_inst(compiler, br(src_r));
+ return push_inst(compiler, brcl(0xf, 0));
}
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_icall(struct sljit_compiler *compiler, sljit_s32 type,
@@ -3711,7 +3879,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_flags(struct sljit_compiler *co
break;
case SLJIT_MOV32:
op |= SLJIT_32;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case SLJIT_MOV:
/* can write straight into destination */
loc_r = dst_r;
@@ -3766,6 +3934,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
sljit_ins mask;
sljit_gpr src_r;
sljit_gpr dst_r = gpr(dst_reg);
+ sljit_s32 is_32bit = (type & SLJIT_32) != 0;
sljit_ins ins;
CHECK_ERROR();
@@ -3773,6 +3942,43 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
ADJUST_LOCAL_OFFSET(src1, src1w);
+ type &= ~SLJIT_32;
+ if (src1 == SLJIT_IMM && is_32bit)
+ src1w = (sljit_s32)src1w;
+
+ if (type & SLJIT_COMPARE_SELECT) {
+ type ^= SLJIT_COMPARE_SELECT;
+ compiler->status_flags_state = SLJIT_CURRENT_FLAGS_SUB | SLJIT_CURRENT_FLAGS_COMPARE;
+
+ if (src1 & SLJIT_MEM) {
+ FAIL_IF(load_word(compiler, tmp0, src1, src1w, is_32bit));
+ src1 = TMP_REG1;
+ src1w = 0;
+ } else if (src1 == SLJIT_IMM) {
+ if (type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL && src1w >= 0 && src1w <= 0x7fff) {
+ ins = is_32bit ? 0xc20f00000000 /* clfi */ : 0xc20e00000000 /* clgfi */;
+ FAIL_IF(push_inst(compiler, ins | R36A(gpr(src2_reg)) | (sljit_ins)src1w));
+ type ^= 0x1;
+ } else if (type >= SLJIT_SIG_LESS && type <= SLJIT_SIG_LESS_EQUAL && is_s20(src1w)) {
+ ins = is_32bit ? 0xc20d00000000 /* cfi */ : 0xc20c00000000 /* cgfi */;
+ FAIL_IF(push_inst(compiler, ins | R36A(gpr(src2_reg)) | ((sljit_ins)src1w & 0xffffffff)));
+ type ^= 0x1;
+ } else {
+ FAIL_IF(push_load_imm_inst(compiler, tmp0, src1w));
+ src1 = TMP_REG1;
+ src1w = 0;
+ }
+ }
+
+ if (FAST_IS_REG(src1)) {
+ if (type >= SLJIT_LESS && type <= SLJIT_LESS_EQUAL)
+ ins = is_32bit ? 0x1500 /* clr */ : 0xb9210000 /* clgr */;
+ else
+ ins = is_32bit ? 0x1900 /* cr */ : 0xb9200000 /* cgr */;
+ FAIL_IF(push_inst(compiler, ins | R4A(gpr(src1)) | R0A(gpr(src2_reg))));
+ }
+ }
+
if (dst_reg != src2_reg) {
if (src1 == dst_reg) {
src1 = src2_reg;
@@ -3780,16 +3986,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
type ^= 0x1;
} else {
if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
- FAIL_IF(load_word(compiler, dst_r, src1, src1w, type & SLJIT_32));
+ FAIL_IF(load_word(compiler, dst_r, src1, src1w, is_32bit));
src1 = src2_reg;
src1w = 0;
type ^= 0x1;
} else
- FAIL_IF(push_inst(compiler, ((type & SLJIT_32) ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(gpr(src2_reg))));
+ FAIL_IF(push_inst(compiler, (is_32bit ? 0x1800 /* lr */ : 0xb9040000 /* lgr */) | R4A(dst_r) | R0A(gpr(src2_reg))));
}
}
- mask = get_cc(compiler, type & ~SLJIT_32);
+ mask = get_cc(compiler, type);
if (src1 & SLJIT_MEM) {
if (src1 & OFFS_REG_MASK) {
@@ -3807,23 +4013,20 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
FAIL_IF(push_load_imm_inst(compiler, tmp1, src1w));
if (src1 & REG_MASK)
- FAIL_IF(push_inst(compiler, 0xb9e80000 /* agrk */ | R12A(tmp1) | R4A(tmp1) | R0A(gpr(src1 & REG_MASK))));
+ FAIL_IF(push_inst(compiler, 0xb9080000 /* agr */ | R4A(tmp1) | R0A(gpr(src1 & REG_MASK))));
src_r = tmp1;
src1w = 0;
} else
src_r = gpr(src1 & REG_MASK);
- ins = (type & SLJIT_32) ? 0xeb00000000f2 /* loc */ : 0xeb00000000e2 /* locg */;
+ ins = is_32bit ? 0xeb00000000f2 /* loc */ : 0xeb00000000e2 /* locg */;
return push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | R28A(src_r) | disp_s20((sljit_s32)src1w));
}
if (src1 == SLJIT_IMM) {
- if (type & SLJIT_32)
- src1w = (sljit_s32)src1w;
-
if (have_lscond2() && is_s16(src1w)) {
- ins = (type & SLJIT_32) ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */;
+ ins = is_32bit ? 0xec0000000042 /* lochi */ : 0xec0000000046 /* locghi */;
return push_inst(compiler, ins | R36A(dst_r) | (mask << 32) | (sljit_ins)(src1w & 0xffff) << 16);
}
@@ -3832,7 +4035,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
} else
src_r = gpr(src1);
- ins = (type & SLJIT_32) ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */;
+ ins = is_32bit ? 0xb9f20000 /* locr */ : 0xb9e20000 /* locgr */;
return push_inst(compiler, ins | (mask << 12) | R4A(dst_r) | R0A(src_r));
}
@@ -4461,40 +4664,52 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_atomic_store(struct sljit_compiler
/* Other instructions */
/* --------------------------------------------------------------------- */
-/* On s390x we build a literal pool to hold constants. This has two main
- advantages:
-
- 1. we only need one instruction in the instruction stream (LGRL)
- 2. we can store 64 bit addresses and use 32 bit offsets
-
- To retrofit the extra information needed to build the literal pool we
- add a new sljit_s390x_const struct that contains the initial value but
- can still be cast to a sljit_const. */
-
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
- struct sljit_s390x_const *const_;
+ struct sljit_const *const_;
sljit_gpr dst_r;
+ int is_32 = 0;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
- const_ = (struct sljit_s390x_const*)ensure_abuf(compiler,
- sizeof(struct sljit_s390x_const));
+ const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
PTR_FAIL_IF(!const_);
set_const((struct sljit_const*)const_, compiler);
- const_->init_value = init_value;
dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
- if (have_genext())
- PTR_FAIL_IF(push_inst(compiler, lgrl(dst_r, 0)));
- else {
- PTR_FAIL_IF(push_inst(compiler, larl(tmp1, 0)));
- PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ if (init_value & 0x100)
+ init_value |= 0xff00;
+ else
+ init_value &= 0xff;
+
+ PTR_FAIL_IF(push_inst(compiler, 0xa7090000 /* lghi */ | R20A(dst_r) | (sljit_ins)(init_value & 0xffff)));
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(store_byte(compiler, dst_r, dst, dstw));
+ return (struct sljit_const*)const_;
+
+ case SLJIT_MOV32:
+ is_32 = 1;
+ SLJIT_FALLTHROUGH
+ case SLJIT_MOV_S32:
+ PTR_FAIL_IF(push_inst(compiler, 0xc00100000000 /* lgfi */ | R36A(dst_r) | (sljit_ins)(init_value & 0xffffffff)));
+ break;
+
+ default:
+ PTR_FAIL_IF(push_inst(compiler, 0xc00f00000000 /* llilf */ | R36A(dst_r) | (sljit_ins)(init_value & 0xffffffff)));
+ PTR_FAIL_IF(push_inst(compiler, 0xc00800000000 /* iihf */ | R36A(dst_r) | (sljit_ins)((init_value >> 32) & 0xffffffff)));
+ break;
}
if (dst & SLJIT_MEM)
- PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, 0 /* always 64-bit */));
+ PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, is_32));
return (struct sljit_const*)const_;
}
@@ -4511,32 +4726,85 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_CACHE_FLUSH(ptr, ptr + 1);
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
- sljit_set_jump_addr(addr, (sljit_uw)new_constant, executable_offset);
+ sljit_u16 *inst = (sljit_u16*)addr;
+ SLJIT_UNUSED_ARG(executable_offset);
+
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
+ SLJIT_ASSERT((inst[0] & 0xff0f) == 0xa709 /* lghi */);
+
+ if (new_constant & 0x100)
+ new_constant |= 0xff00;
+ else
+ new_constant &= 0xff;
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 0);
+ inst[1] = (sljit_u16)new_constant;
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 2, 1);
+ inst = (sljit_u16*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 2);
+ return;
+
+ case SLJIT_MOV32:
+ case SLJIT_MOV_S32:
+ SLJIT_ASSERT((inst[0] & 0xff0f) == 0xc001 /* lgfi */);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 3, 0);
+ inst[1] = (sljit_u16)(new_constant >> 16);
+ inst[2] = (sljit_u16)new_constant;
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 3, 1);
+ inst = (sljit_u16*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 3);
+ return;
+
+ default:
+ SLJIT_ASSERT((inst[0] & 0xff0f) == 0xc00f /* llilf */ && (inst[3] & 0xff0f) == 0xc008 /* iihf */);
+
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 0);
+ inst[1] = (sljit_u16)(new_constant >> 16);
+ inst[2] = (sljit_u16)new_constant;
+ inst[4] = (sljit_u16)(new_constant >> 48);
+ inst[5] = (sljit_u16)(new_constant >> 32);
+ SLJIT_UPDATE_WX_FLAGS(inst, inst + 6, 1);
+ inst = (sljit_u16*)SLJIT_ADD_EXEC_OFFSET(inst, executable_offset);
+ SLJIT_CACHE_FLUSH(inst, inst + 6);
+ return;
+ }
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
- sljit_gpr dst_r;
+ sljit_gpr dst_r, target_r;
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+
+ if (op != SLJIT_ADD_ABS_ADDR)
+ target_r = dst_r;
+ else {
+ target_r = tmp1;
+
+ if (dst & SLJIT_MEM)
+ PTR_FAIL_IF(load_word(compiler, dst_r, dst, dstw, 0));
+ }
+
jump = (struct sljit_jump*)ensure_abuf(compiler, sizeof(struct sljit_jump));
PTR_FAIL_IF(!jump);
set_mov_addr(jump, compiler, 0);
- dst_r = FAST_IS_REG(dst) ? gpr(dst & REG_MASK) : tmp0;
+ /* Might be converted to lgrl. */
+ PTR_FAIL_IF(push_inst(compiler, 0xc00000000000 /* larl */ | R36A(target_r)));
- if (have_genext())
- PTR_FAIL_IF(push_inst(compiler, lgrl(dst_r, 0)));
- else {
- PTR_FAIL_IF(push_inst(compiler, larl(tmp1, 0)));
- PTR_FAIL_IF(push_inst(compiler, lg(dst_r, 0, r0, tmp1)));
- }
+ if (op == SLJIT_ADD_ABS_ADDR)
+ PTR_FAIL_IF(push_inst(compiler, 0xb90a0000 /* algr */ | R4A(dst_r) | R0A(tmp1)));
if (dst & SLJIT_MEM)
PTR_FAIL_IF(store_word(compiler, dst_r, dst, dstw, 0));
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_32.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_32.c
index 217a1498abe..95faa74ffbf 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_32.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_32.c
@@ -105,20 +105,20 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw
if (a == SLJIT_IMM) {
if (flags & EX86_BIN_INS) {
if (imma <= 127 && imma >= -128) {
- inst_size += 1;
+ inst_size += sizeof(sljit_s8);
flags |= EX86_BYTE_ARG;
} else
- inst_size += 4;
+ inst_size += sizeof(sljit_sw);
} else if (flags & EX86_SHIFT_INS) {
SLJIT_ASSERT(imma <= 0x1f);
if (imma != 1) {
- inst_size++;
+ inst_size += sizeof(sljit_s8);
flags |= EX86_BYTE_ARG;
}
} else if (flags & EX86_BYTE_ARG)
- inst_size++;
+ inst_size += sizeof(sljit_s8);
else if (flags & EX86_HALF_ARG)
- inst_size += sizeof(short);
+ inst_size += sizeof(sljit_s16);
else
inst_size += sizeof(sljit_sw);
} else
@@ -1268,41 +1268,59 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
CHECK_EXTRA_REGS(src1, src1w, (void)0);
CHECK_EXTRA_REGS(src2_reg, src2w, (void)0);
- type &= ~SLJIT_32;
-
if (dst & SLJIT_MEM) {
if (src1 == SLJIT_IMM || (!(src1 & SLJIT_MEM) && (src2_reg & SLJIT_MEM))) {
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
src1 = src2_reg;
src1w = src2w;
- type ^= 0x1;
+ if (!(type & SLJIT_COMPARE_SELECT))
+ type ^= 0x1;
} else
EMIT_MOV(compiler, TMP_REG1, 0, src2_reg, src2w);
dst_reg = TMP_REG1;
- } else {
- if (dst_reg != src2_reg) {
- if (dst_reg == src1) {
- src1 = src2_reg;
- src1w = src2w;
+ } else if (dst_reg != src2_reg) {
+ if (dst_reg == src1) {
+ src1 = src2_reg;
+ src1w = src2w;
+ if (!(type & SLJIT_COMPARE_SELECT))
type ^= 0x1;
- } else if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
- EMIT_MOV(compiler, dst_reg, 0, src1, src1w);
- src1 = src2_reg;
- src1w = src2w;
+ } else if (ADDRESSING_DEPENDS_ON(src1, dst_reg)) {
+ EMIT_MOV(compiler, dst_reg, 0, src1, src1w);
+ src1 = src2_reg;
+ src1w = src2w;
+ if (!(type & SLJIT_COMPARE_SELECT))
type ^= 0x1;
- } else
- EMIT_MOV(compiler, dst_reg, 0, src2_reg, src2w);
- }
+ } else
+ EMIT_MOV(compiler, dst_reg, 0, src2_reg, src2w);
}
- if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && (src1 != SLJIT_IMM || dst_reg != TMP_REG1)) {
- if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {
+ if (type & SLJIT_COMPARE_SELECT) {
+ if (dst_reg != TMP_REG1 && !FAST_IS_REG(src1)) {
EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
src1 = TMP_REG1;
src1w = 0;
}
+ type ^= 0x1;
+ FAIL_IF(emit_cmp_binary(compiler, dst_reg, 0, src1, src1w));
+ }
+
+ type &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);
+
+ if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) {
+ if (SLJIT_UNLIKELY(src1 == SLJIT_IMM)) {
+ if (dst_reg != TMP_REG1) {
+ EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_IMM, src1w);
+ src1 = TMP_REG1;
+ src1w = 0;
+ } else {
+ EMIT_MOV(compiler, SLJIT_MEM1(SLJIT_SP), 0, SLJIT_IMM, src1w);
+ src1 = SLJIT_MEM1(SLJIT_SP);
+ src1w = 0;
+ }
+ }
+
FAIL_IF(emit_groupf(compiler, U8(get_jump_code((sljit_uw)type) - 0x40), dst_reg, src1, src1w));
} else
FAIL_IF(emit_cmov_generic(compiler, type, dst_reg, src1, src1w));
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_64.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_64.c
index e4d3db828fa..0a2f59d2959 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_64.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_64.c
@@ -152,20 +152,20 @@ static sljit_u8* emit_x86_instruction(struct sljit_compiler *compiler, sljit_uw
if (a == SLJIT_IMM) {
if (flags & EX86_BIN_INS) {
if (imma <= 127 && imma >= -128) {
- inst_size += 1;
+ inst_size += sizeof(sljit_s8);
flags |= EX86_BYTE_ARG;
} else
- inst_size += 4;
+ inst_size += sizeof(sljit_s32);
} else if (flags & EX86_SHIFT_INS) {
SLJIT_ASSERT(imma <= (compiler->mode32 ? 0x1f : 0x3f));
if (imma != 1) {
- inst_size++;
+ inst_size += sizeof(sljit_s8);
flags |= EX86_BYTE_ARG;
}
} else if (flags & EX86_BYTE_ARG)
- inst_size++;
+ inst_size += sizeof(sljit_s8);
else if (flags & EX86_HALF_ARG)
- inst_size += sizeof(short);
+ inst_size += sizeof(sljit_s16);
else
inst_size += sizeof(sljit_s32);
} else {
@@ -362,7 +362,7 @@ static sljit_u8* detect_far_jump_type(struct sljit_jump *jump, sljit_u8 *code_pt
{
sljit_uw type = jump->flags >> TYPE_SHIFT;
- int short_addr = !(jump->flags & SLJIT_REWRITABLE_JUMP) && (jump->flags & JUMP_ADDR) && (jump->u.target <= 0xffffffff);
+ int short_addr = ((jump->flags & (SLJIT_REWRITABLE_JUMP | JUMP_ADDR)) == JUMP_ADDR) && (jump->u.target <= 0xffffffff);
/* The relative jump below specialized for this case. */
SLJIT_ASSERT(reg_map[TMP_REG2] >= 8 && TMP_REG2 != SLJIT_TMP_DEST_REG);
@@ -805,7 +805,7 @@ static sljit_s32 call_with_args(struct sljit_compiler *compiler, sljit_s32 arg_t
if (word_arg_count == 0)
return SLJIT_SUCCESS;
- if (word_arg_count >= 3) {
+ if (word_arg_count >= 3 || src == SLJIT_R2) {
if (src == SLJIT_R2)
*src_ptr = TMP_REG1;
EMIT_MOV(compiler, TMP_REG1, 0, SLJIT_R2, 0);
@@ -1029,13 +1029,28 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_select(struct sljit_compiler *comp
sljit_s32 src1, sljit_sw src1w,
sljit_s32 src2_reg)
{
+ sljit_u8* inst;
+
CHECK_ERROR();
CHECK(check_sljit_emit_select(compiler, type, dst_reg, src1, src1w, src2_reg));
ADJUST_LOCAL_OFFSET(src1, src1w);
compiler->mode32 = type & SLJIT_32;
- type &= ~SLJIT_32;
+
+ if (type & SLJIT_COMPARE_SELECT) {
+ if (!FAST_IS_REG(src1)) {
+ EMIT_MOV(compiler, TMP_REG2, 0, src1, src1w);
+ src1 = TMP_REG2;
+ src1w = 0;
+ }
+
+ inst = emit_x86_instruction(compiler, 1, src1, 0, src2_reg, 0);
+ FAIL_IF(!inst);
+ *inst = CMP_r_rm;
+ }
+
+ type &= ~(SLJIT_32 | SLJIT_COMPARE_SELECT);
if (dst_reg != src2_reg) {
if (dst_reg == src1) {
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_common.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_common.c
index 9f599d5fb08..25085a8f9f1 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_common.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitNativeX86_common.c
@@ -780,6 +780,22 @@ static void generate_jump_or_mov_addr(struct sljit_jump *jump, sljit_sw executab
}
}
+static sljit_u8 *process_extended_label(sljit_u8 *code_ptr, struct sljit_extended_label *ext_label)
+{
+ sljit_uw mask;
+ sljit_u8 *ptr = code_ptr;
+
+ SLJIT_ASSERT(ext_label->label.u.index == SLJIT_LABEL_ALIGNED);
+ mask = ext_label->data;
+
+ code_ptr = (sljit_u8*)(((sljit_uw)code_ptr + mask) & ~mask);
+
+ while (ptr < code_ptr)
+ *ptr++ = NOP;
+
+ return code_ptr;
+}
+
static void reduce_code_size(struct sljit_compiler *compiler)
{
struct sljit_label *label;
@@ -914,7 +930,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
struct sljit_const *const_;
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_generate_code(compiler));
+ CHECK_PTR(check_sljit_generate_code(compiler, options));
reduce_code_size(compiler);
@@ -944,6 +960,9 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
} else {
switch (len) {
case SLJIT_INST_LABEL:
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ code_ptr = process_extended_label(code_ptr, (struct sljit_extended_label*)label);
+
label->u.addr = (sljit_uw)SLJIT_ADD_EXEC_OFFSET(code_ptr, executable_offset);
label->size = (sljit_uw)(code_ptr - code);
label = label->next;
@@ -962,7 +981,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
#endif /* SLJIT_CONFIG_X86_32 */
}
- SLJIT_ASSERT((sljit_uw)code_ptr - addr <= ((jump->flags >> JUMP_SIZE_SHIFT) & 0x1f));
+ SLJIT_ASSERT((sljit_uw)code_ptr - addr <= ((jump->flags >> JUMP_SIZE_SHIFT) & 0xff));
jump = jump->next;
break;
case SLJIT_INST_MOV_ADDR:
@@ -974,7 +993,7 @@ SLJIT_API_FUNC_ATTRIBUTE void* sljit_generate_code(struct sljit_compiler *compil
break;
default:
SLJIT_ASSERT(len == SLJIT_INST_CONST);
- const_->addr = ((sljit_uw)code_ptr) - sizeof(sljit_sw);
+ const_->addr = (sljit_uw)code_ptr;
const_ = const_->next;
break;
}
@@ -2998,6 +3017,125 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_shift_into(struct sljit_compiler *
return SLJIT_SUCCESS;
}
+SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op2_shift(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_s32 src1, sljit_sw src1w,
+ sljit_s32 src2, sljit_sw src2w,
+ sljit_sw shift_arg)
+{
+ sljit_s32 dst_r;
+ int use_lea = 0;
+ sljit_u8* inst;
+
+ CHECK_ERROR();
+ CHECK(check_sljit_emit_op2_shift(compiler, op, dst, dstw, src1, src1w, src2, src2w, shift_arg));
+ ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(src1, src1w);
+ ADJUST_LOCAL_OFFSET(src2, src2w);
+
+ shift_arg &= (sljit_sw)((sizeof(sljit_sw) * 8) - 1);
+
+ if (src2 == SLJIT_IMM) {
+ src2w = src2w << shift_arg;
+ shift_arg = 0;
+ }
+
+ if (shift_arg == 0) {
+ SLJIT_SKIP_CHECKS(compiler);
+ return sljit_emit_op2(compiler, GET_OPCODE(op), dst, dstw, src1, src1w, src2, src2w);
+ }
+
+ CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ CHECK_EXTRA_REGS(src1, src1w, (void)0);
+ CHECK_EXTRA_REGS(src2, src2w, (void)0);
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = 0;
+#endif
+
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (shift_arg <= 3) {
+ use_lea = 1;
+ if (!FAST_IS_REG(src2)) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);
+ src2 = TMP_REG1;
+ }
+
+ if (!FAST_IS_REG(src1)) {
+ EMIT_MOV(compiler, src2 == TMP_REG1 ? TMP_REG2 : TMP_REG1, 0, src1, src1w);
+ src1 = src2 == TMP_REG1 ? TMP_REG2 : TMP_REG1;
+ }
+ }
+#else /* !SLJIT_CONFIG_X86_64 */
+ if (shift_arg <= 3 && (FAST_IS_REG(src1) || (FAST_IS_REG(src2) && src2 != TMP_REG1))) {
+ use_lea = 1;
+ if (!FAST_IS_REG(src2)) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src2, src2w);
+ src2 = TMP_REG1;
+ }
+
+ if (!FAST_IS_REG(src1)) {
+ EMIT_MOV(compiler, TMP_REG1, 0, src1, src1w);
+ src1 = TMP_REG1;
+ }
+ }
+#endif /* SLJIT_CONFIG_X86_64 */
+
+ if (use_lea) {
+ dst_r = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, SLJIT_MEM2(src1, src2), shift_arg);
+ FAIL_IF(!inst);
+ *inst = LEA_r_m;
+
+ if (!FAST_IS_REG(dst))
+ return emit_mov(compiler, dst, dstw, dst_r, 0);
+
+ return SLJIT_SUCCESS;
+ }
+
+ if ((op & SLJIT_SRC2_UNDEFINED) != 0 && FAST_IS_REG(src2) && src1 != src2)
+ dst_r = src2;
+ else {
+ dst_r = FAST_IS_REG(dst) && (dst != src1) ? dst : TMP_REG1;
+
+ if (src2 != dst_r) {
+ EMIT_MOV(compiler, dst_r, 0, src2, src2w);
+ }
+ }
+
+ inst = emit_x86_instruction(compiler, 1 | EX86_SHIFT_INS, SLJIT_IMM, shift_arg, dst_r, 0);
+ FAIL_IF(!inst);
+ inst[1] |= SHL;
+
+ if (dst == src1 && dstw == src1w) {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, dst, dstw);
+ FAIL_IF(!inst);
+ *inst = ADD_rm_r;
+ return SLJIT_SUCCESS;
+ }
+
+ if (FAST_IS_REG(dst) && FAST_IS_REG(src1)) {
+ inst = emit_x86_instruction(compiler, 1, dst, 0, SLJIT_MEM2(src1, dst_r), 0);
+ FAIL_IF(!inst);
+ *inst = LEA_r_m;
+ return SLJIT_SUCCESS;
+ }
+
+ if (src1 == SLJIT_IMM) {
+ BINARY_IMM(ADD, ADD_rm_r, src1w, dst_r, 0);
+ } else {
+ inst = emit_x86_instruction(compiler, 1, dst_r, 0, src1, src1w);
+ FAIL_IF(!inst);
+ *inst = ADD_r_rm;
+ }
+
+ if (dst != dst_r)
+ return emit_mov(compiler, dst, dstw, dst_r, 0);
+
+ return SLJIT_SUCCESS;
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op_src(struct sljit_compiler *compiler, sljit_s32 op,
sljit_s32 src, sljit_sw srcw)
{
@@ -3438,6 +3576,82 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_label(struct sljit_compi
return label;
}
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_label* sljit_emit_aligned_label(struct sljit_compiler *compiler,
+ sljit_s32 alignment, struct sljit_read_only_buffer *buffers)
+{
+ sljit_uw mask, size;
+ sljit_u8 *inst;
+ struct sljit_label *label;
+ struct sljit_label *next_label;
+ struct sljit_extended_label *ext_label;
+
+ CHECK_ERROR_PTR();
+ CHECK_PTR(check_sljit_emit_aligned_label(compiler, alignment, buffers));
+
+ sljit_reset_read_only_buffers(buffers);
+
+ if (alignment <= SLJIT_LABEL_ALIGN_1) {
+ SLJIT_SKIP_CHECKS(compiler);
+ label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!label);
+ } else {
+ /* The used space is filled with NOPs. */
+ mask = ((sljit_uw)1 << alignment) - 1;
+ compiler->size += mask;
+
+ inst = (sljit_u8*)ensure_buf(compiler, 1);
+ PTR_FAIL_IF(!inst);
+ inst[0] = SLJIT_INST_LABEL;
+
+ ext_label = (struct sljit_extended_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ PTR_FAIL_IF(!ext_label);
+ set_extended_label(ext_label, compiler, SLJIT_LABEL_ALIGNED, mask);
+ label = &ext_label->label;
+ }
+
+ if (buffers == NULL)
+ return label;
+
+ next_label = label;
+
+ while (1) {
+ buffers->u.label = next_label;
+ size = buffers->size;
+
+ while (size >= 4) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + 4);
+ PTR_FAIL_IF(!inst);
+ INC_SIZE(4);
+ inst[0] = NOP;
+ inst[1] = NOP;
+ inst[2] = NOP;
+ inst[3] = NOP;
+ size -= 4;
+ }
+
+ if (size > 0) {
+ inst = (sljit_u8*)ensure_buf(compiler, 1 + size);
+ PTR_FAIL_IF(!inst);
+ INC_SIZE(size);
+
+ do {
+ *inst++ = NOP;
+ } while (--size != 0);
+ }
+
+ buffers = buffers->next;
+
+ if (buffers == NULL)
+ break;
+
+ SLJIT_SKIP_CHECKS(compiler);
+ next_label = sljit_emit_label(compiler);
+ PTR_FAIL_IF(!next_label);
+ }
+
+ return label;
+}
+
SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type)
{
sljit_u8 *inst;
@@ -3965,7 +4179,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_replicate(struct sljit_compil
else
FAIL_IF(emit_groupf(compiler, PSHUFLW_x_xm | EX86_PREF_F2 | EX86_SSE2, vreg, vreg, 0));
FAIL_IF(emit_byte(compiler, 0));
- /* fallthrough */
+ SLJIT_FALLTHROUGH
default:
if (use_vex)
FAIL_IF(emit_vex_instruction(compiler, PSHUFD_x_xm | EX86_PREF_66 | EX86_SSE2, vreg, 0, vreg, 0));
@@ -4539,7 +4753,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_simd_lane_replicate(struct sljit_c
return emit_vex_instruction(compiler, VPBROADCASTD_x_xm | EX86_PREF_66 | VEX_OP_0F38 | EX86_SSE2, vreg, 0, vreg, 0);
src = vreg;
- /* fallthrough */
+ SLJIT_FALLTHROUGH
case 2:
byte = U8(src_lane_index);
byte = U8(byte | (byte << 2));
@@ -5002,6 +5216,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
CHECK_ERROR();
CHECK(check_sljit_get_local_base(compiler, dst, dstw, offset));
ADJUST_LOCAL_OFFSET(dst, dstw);
+ ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
CHECK_EXTRA_REGS(dst, dstw, (void)0);
@@ -5009,8 +5224,6 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
compiler->mode32 = 0;
#endif
- ADJUST_LOCAL_OFFSET(SLJIT_MEM1(SLJIT_SP), offset);
-
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
if (NOT_HALFWORD(offset)) {
FAIL_IF(emit_load_imm64(compiler, TMP_REG1, offset));
@@ -5028,59 +5241,105 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_get_local_base(struct sljit_compiler *c
return emit_mov(compiler, dst, dstw, SLJIT_SP, 0);
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw, sljit_sw init_value)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_const* sljit_emit_const(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw,
+ sljit_sw init_value)
{
sljit_u8 *inst;
struct sljit_const *const_;
-#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
sljit_s32 reg;
-#endif
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ sljit_s32 dst_is_ereg = 0;
+#endif /* !SLJIT_CONFIG_X86_32 */
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_const(compiler, dst, dstw, init_value));
+ CHECK_PTR(check_sljit_emit_const(compiler, op, dst, dstw, init_value));
ADJUST_LOCAL_OFFSET(dst, dstw);
- CHECK_EXTRA_REGS(dst, dstw, (void)0);
+ CHECK_EXTRA_REGS(dst, dstw, dst_is_ereg = 1);
const_ = (struct sljit_const*)ensure_abuf(compiler, sizeof(struct sljit_const));
PTR_FAIL_IF(!const_);
set_const(const_, compiler);
+ switch (GET_OPCODE(op)) {
+ case SLJIT_MOV_U8:
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- compiler->mode32 = 0;
- reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
+ compiler->mode32 = (op & SLJIT_32);
+#endif /* SLJIT_CONFIG_X86_64 */
- if (emit_load_imm64(compiler, reg, init_value))
- return NULL;
-#else
- if (emit_mov(compiler, dst, dstw, SLJIT_IMM, init_value))
- return NULL;
-#endif
+ if ((init_value & 0x100) != 0)
+ init_value = init_value | -(sljit_sw)0x100;
+ else
+ init_value = (sljit_u8)init_value;
+
+#if (defined SLJIT_CONFIG_X86_32 && SLJIT_CONFIG_X86_32)
+ if (dst_is_ereg) {
+ if (emit_mov(compiler, dst, dstw, SLJIT_IMM, (sljit_s32)init_value))
+ return NULL;
+ dst = 0;
+ break;
+ }
+#endif /* !SLJIT_CONFIG_X86_32 */
+
+ reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if (emit_mov(compiler, reg, 0, SLJIT_IMM, init_value))
+ return NULL;
+ break;
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ case SLJIT_MOV:
+ compiler->mode32 = 0;
+ reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
+
+ if (emit_load_imm64(compiler, reg, init_value))
+ return NULL;
+ break;
+#endif /* SLJIT_CONFIG_X86_64 */
+ default:
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ compiler->mode32 = (op == SLJIT_MOV32);
+#endif /* SLJIT_CONFIG_X86_64 */
+
+ if (emit_mov(compiler, dst, dstw, SLJIT_IMM, (sljit_s32)init_value))
+ return NULL;
+ dst = 0;
+ break;
+ }
inst = (sljit_u8*)ensure_buf(compiler, 1);
PTR_FAIL_IF(!inst);
inst[0] = SLJIT_INST_CONST;
+ if (dst & SLJIT_MEM) {
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (dst & SLJIT_MEM)
- if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
- return NULL;
+ if (op == SLJIT_MOV) {
+ if (emit_mov(compiler, dst, dstw, TMP_REG1, 0))
+ return NULL;
+ return const_;
+ }
#endif
+ if (emit_mov_byte(compiler, 0, dst, dstw, TMP_REG1, 0))
+ return NULL;
+ }
+
return const_;
}
-SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_compiler *compiler, sljit_s32 dst, sljit_sw dstw)
+SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_op_addr(struct sljit_compiler *compiler, sljit_s32 op,
+ sljit_s32 dst, sljit_sw dstw)
{
struct sljit_jump *jump;
sljit_u8 *inst;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
sljit_s32 reg;
#endif /* SLJIT_CONFIG_X86_64 */
+ SLJIT_UNUSED_ARG(op);
CHECK_ERROR_PTR();
- CHECK_PTR(check_sljit_emit_mov_addr(compiler, dst, dstw));
+ CHECK_PTR(check_sljit_emit_op_addr(compiler, op, dst, dstw));
ADJUST_LOCAL_OFFSET(dst, dstw);
CHECK_EXTRA_REGS(dst, dstw, (void)0);
@@ -5091,7 +5350,10 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_com
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
compiler->mode32 = 0;
- reg = FAST_IS_REG(dst) ? dst : TMP_REG1;
+ if (dst & SLJIT_MEM)
+ reg = TMP_REG1;
+ else
+ reg = (op != SLJIT_ADD_ABS_ADDR) ? dst : TMP_REG2;
PTR_FAIL_IF(emit_load_imm64(compiler, reg, 0));
jump->addr = compiler->size;
@@ -5099,7 +5361,17 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_com
if (reg_map[reg] >= 8)
jump->flags |= MOV_ADDR_HI;
#else /* !SLJIT_CONFIG_X86_64 */
- PTR_FAIL_IF(emit_mov(compiler, dst, dstw, SLJIT_IMM, 0));
+ if (op == SLJIT_ADD_ABS_ADDR) {
+ if (dst != SLJIT_R0) {
+ /* Must not be a signed byte argument. */
+ inst = emit_x86_instruction(compiler, 1 | EX86_BIN_INS, SLJIT_IMM, 0x100, dst, dstw);
+ PTR_FAIL_IF(!inst);
+ *(inst + 1) |= ADD;
+ } else
+ PTR_FAIL_IF(emit_do_imm(compiler, ADD_EAX_i32, 0));
+ } else {
+ PTR_FAIL_IF(emit_mov(compiler, dst, dstw, SLJIT_IMM, 0));
+ }
#endif /* SLJIT_CONFIG_X86_64 */
inst = (sljit_u8*)ensure_buf(compiler, 1);
@@ -5108,7 +5380,11 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_mov_addr(struct sljit_com
inst[0] = SLJIT_INST_MOV_ADDR;
#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
- if (dst & SLJIT_MEM)
+ if (op == SLJIT_ADD_ABS_ADDR) {
+ inst = emit_x86_instruction(compiler, 1, reg, 0, dst, dstw);
+ PTR_FAIL_IF(!inst);
+ *inst = ADD_rm_r;
+ } else if (dst & SLJIT_MEM)
PTR_FAIL_IF(emit_mov(compiler, dst, dstw, TMP_REG1, 0));
#endif /* SLJIT_CONFIG_X86_64 */
@@ -5128,11 +5404,31 @@ SLJIT_API_FUNC_ATTRIBUTE void sljit_set_jump_addr(sljit_uw addr, sljit_uw new_ta
SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_uw)), 1);
}
-SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_sw new_constant, sljit_sw executable_offset)
+SLJIT_API_FUNC_ATTRIBUTE void sljit_set_const(sljit_uw addr, sljit_s32 op, sljit_sw new_constant, sljit_sw executable_offset)
{
+ void *start_addr;
SLJIT_UNUSED_ARG(executable_offset);
- SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 0);
- sljit_unaligned_store_sw((void*)addr, new_constant);
- SLJIT_UPDATE_WX_FLAGS((void*)addr, (void*)(addr + sizeof(sljit_sw)), 1);
+#if (defined SLJIT_CONFIG_X86_64 && SLJIT_CONFIG_X86_64)
+ if (op == SLJIT_MOV) {
+ start_addr = (void*)(addr - sizeof(sljit_sw));
+ SLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 0);
+ sljit_unaligned_store_sw(start_addr, new_constant);
+ SLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 1);
+ return;
+ }
+#endif
+
+ start_addr = (void*)(addr - sizeof(sljit_s32));
+
+ if ((op | SLJIT_32) == SLJIT_MOV32_U8) {
+ if ((new_constant & 0x100) != 0)
+ new_constant = new_constant | -(sljit_sw)0x100;
+ else
+ new_constant = (sljit_u8)new_constant;
+ }
+
+ SLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 0);
+ sljit_unaligned_store_s32(start_addr, (sljit_s32)new_constant);
+ SLJIT_UPDATE_WX_FLAGS(start_addr, (void*)addr, 1);
}
diff --git a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c
index 6ef161fd498..042cc18a89e 100644
--- a/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c
+++ b/src/3rdparty/pcre2/deps/sljit/sljit_src/sljitSerialize.c
@@ -24,6 +24,14 @@
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#define SLJIT_GET_LABEL_INDEX(label) \
+ ((label)->u.index < SLJIT_LABEL_ALIGNED ? (label)->u.index : ((struct sljit_extended_label*)(label))->index)
+
+SLJIT_API_FUNC_ATTRIBUTE sljit_uw sljit_get_label_index(struct sljit_label *label)
+{
+ return SLJIT_GET_LABEL_INDEX(label);
+}
+
SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_jump_has_label(struct sljit_jump *jump)
{
return !(jump->flags & JUMP_ADDR) && (jump->u.label != NULL);
@@ -48,6 +56,7 @@ struct sljit_serialized_compiler {
sljit_uw buf_segment_count;
sljit_uw label_count;
+ sljit_uw aligned_label_count;
sljit_uw jump_count;
sljit_uw const_count;
@@ -94,6 +103,11 @@ struct sljit_serialized_label {
sljit_uw size;
};
+struct sljit_serialized_aligned_label {
+ sljit_uw size;
+ sljit_uw data;
+};
+
struct sljit_serialized_jump {
sljit_uw addr;
sljit_uw flags;
@@ -122,6 +136,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compile
struct sljit_const *const_;
struct sljit_serialized_compiler *serialized_compiler;
struct sljit_serialized_label *serialized_label;
+ struct sljit_serialized_aligned_label *serialized_aligned_label;
struct sljit_serialized_jump *serialized_jump;
struct sljit_serialized_const *serialized_const;
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
@@ -155,7 +170,16 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compile
buf = buf->next;
}
- serialized_size += compiler->label_count * sizeof(struct sljit_serialized_label);
+ label = compiler->labels;
+ while (label != NULL) {
+ used_size = sizeof(struct sljit_serialized_label);
+
+ if (label->u.index >= SLJIT_LABEL_ALIGNED)
+ used_size += sizeof(struct sljit_serialized_aligned_label);
+
+ serialized_size += used_size;
+ label = label->next;
+ }
jump = compiler->jumps;
while (jump != NULL) {
@@ -229,12 +253,23 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compile
serialized_compiler->buf_segment_count = counter;
label = compiler->labels;
+ counter = 0;
while (label != NULL) {
serialized_label = (struct sljit_serialized_label*)ptr;
- serialized_label->size = label->size;
+ serialized_label->size = (label->u.index < SLJIT_LABEL_ALIGNED) ? label->size : label->u.index;
ptr += sizeof(struct sljit_serialized_label);
+
+ if (label->u.index >= SLJIT_LABEL_ALIGNED) {
+ serialized_aligned_label = (struct sljit_serialized_aligned_label*)ptr;
+ serialized_aligned_label->size = label->size;
+ serialized_aligned_label->data = ((struct sljit_extended_label*)label)->data;
+ ptr += sizeof(struct sljit_serialized_aligned_label);
+ counter++;
+ }
+
label = label->next;
}
+ serialized_compiler->aligned_label_count = counter;
jump = compiler->jumps;
counter = 0;
@@ -246,7 +281,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_uw* sljit_serialize_compiler(struct sljit_compile
if (jump->flags & JUMP_ADDR)
serialized_jump->value = jump->u.target;
else if (jump->u.label != NULL)
- serialized_jump->value = jump->u.label->u.index;
+ serialized_jump->value = SLJIT_GET_LABEL_INDEX(jump->u.label);
else
serialized_jump->value = SLJIT_MAX_ADDRESS;
@@ -291,6 +326,7 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit
struct sljit_compiler *compiler;
struct sljit_serialized_compiler *serialized_compiler;
struct sljit_serialized_label *serialized_label;
+ struct sljit_serialized_aligned_label *serialized_aligned_label;
struct sljit_serialized_jump *serialized_jump;
struct sljit_serialized_const *serialized_const;
#if (defined SLJIT_ARGUMENT_CHECKS && SLJIT_ARGUMENT_CHECKS) \
@@ -302,13 +338,15 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit
struct sljit_label *label;
struct sljit_label *last_label;
struct sljit_label **label_list = NULL;
+ struct sljit_label **label_list_ptr = NULL;
struct sljit_jump *jump;
struct sljit_jump *last_jump;
struct sljit_const *const_;
struct sljit_const *last_const;
sljit_u8 *ptr = (sljit_u8*)buffer;
sljit_u8 *end = ptr + size;
- sljit_uw i, used_size, aligned_size, label_count;
+ sljit_uw i, type, used_size, aligned_size;
+ sljit_uw label_count, aligned_label_count;
SLJIT_UNUSED_ARG(options);
if (size < sizeof(struct sljit_serialized_compiler) || (size & (sizeof(sljit_uw) - 1)) != 0)
@@ -403,22 +441,31 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit
last_label = NULL;
label_count = serialized_compiler->label_count;
- if ((sljit_uw)(end - ptr) < label_count * sizeof(struct sljit_serialized_label))
+ aligned_label_count = serialized_compiler->aligned_label_count;
+ i = (label_count * sizeof(struct sljit_serialized_label)) + (aligned_label_count * sizeof(struct sljit_serialized_aligned_label));
+
+ if ((sljit_uw)(end - ptr) < i)
goto error;
label_list = (struct sljit_label **)SLJIT_MALLOC(label_count * sizeof(struct sljit_label*), allocator_data);
if (label_list == NULL)
goto error;
+ label_list_ptr = label_list;
for (i = 0; i < label_count; i++) {
- label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ serialized_label = (struct sljit_serialized_label*)ptr;
+ type = serialized_label->size;
+
+ if (type < SLJIT_LABEL_ALIGNED) {
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_label));
+ } else {
+ label = (struct sljit_label*)ensure_abuf(compiler, sizeof(struct sljit_extended_label));
+ }
+
if (label == NULL)
goto error;
- serialized_label = (struct sljit_serialized_label*)ptr;
label->next = NULL;
- label->u.index = i;
- label->size = serialized_label->size;
if (last_label != NULL)
last_label->next = label;
@@ -426,11 +473,33 @@ SLJIT_API_FUNC_ATTRIBUTE struct sljit_compiler *sljit_deserialize_compiler(sljit
compiler->labels = label;
last_label = label;
- label_list[i] = label;
+ *label_list_ptr++ = label;
+
ptr += sizeof(struct sljit_serialized_label);
+
+ if (type < SLJIT_LABEL_ALIGNED) {
+ label->u.index = i;
+ label->size = type;
+ } else {
+ if (aligned_label_count == 0)
+ goto error;
+
+ aligned_label_count--;
+
+ serialized_aligned_label = (struct sljit_serialized_aligned_label*)ptr;
+ label->u.index = type;
+ label->size = serialized_aligned_label->size;
+
+ ((struct sljit_extended_label*)label)->index = i;
+ ((struct sljit_extended_label*)label)->data = serialized_aligned_label->data;
+ ptr += sizeof(struct sljit_serialized_aligned_label);
+ }
}
compiler->last_label = last_label;
+ if (aligned_label_count != 0)
+ goto error;
+
last_jump = NULL;
i = serialized_compiler->jump_count;
if ((sljit_uw)(end - ptr) < i * sizeof(struct sljit_serialized_jump))
diff --git a/src/3rdparty/pcre2/import_from_pcre2_tarball.sh b/src/3rdparty/pcre2/import_from_pcre2_tarball.sh
index 15471203707..3a8c29bf010 100755
--- a/src/3rdparty/pcre2/import_from_pcre2_tarball.sh
+++ b/src/3rdparty/pcre2/import_from_pcre2_tarball.sh
@@ -44,6 +44,7 @@ copy_file() {
copy_file "src/pcre2.h.generic" "src/pcre2.h"
copy_file "src/pcre2_chartables.c.dist" "src/pcre2_chartables.c"
+copy_file "deps/sljit/LICENSE" "LICENSE-SLJIT"
FILES="
AUTHORS.md
@@ -53,6 +54,7 @@ FILES="
src/pcre2_chkdint.c
src/pcre2_compile.c
src/pcre2_compile.h
+ src/pcre2_compile_cgroup.c
src/pcre2_compile_class.c
src/pcre2_config.c
src/pcre2_context.c
@@ -63,8 +65,6 @@ FILES="
src/pcre2_internal.h
src/pcre2_intmodedep.h
src/pcre2_jit_compile.c
- src/pcre2_jit_match.c
- src/pcre2_jit_misc.c
src/pcre2_maketables.c
src/pcre2_match.c
src/pcre2_match_data.c
@@ -74,7 +74,8 @@ FILES="
src/pcre2_script_run.c
src/pcre2_serialize.c
src/pcre2_jit_char_inc.h
- src/pcre2_jit_neon_inc.h
+ src/pcre2_jit_match_inc.h
+ src/pcre2_jit_misc_inc.h
src/pcre2_jit_simd_inc.h
src/pcre2_string_utils.c
src/pcre2_study.c
@@ -83,7 +84,7 @@ FILES="
src/pcre2_tables.c
src/pcre2_ucd.c
src/pcre2_ucp.h
- src/pcre2_ucptables.c
+ src/pcre2_ucptables_inc.h
src/pcre2_util.h
src/pcre2_valid_utf.c
src/pcre2_xclass.c
diff --git a/src/3rdparty/pcre2/qt_attribution.json b/src/3rdparty/pcre2/qt_attribution.json
index 20b841eec6f..ef29ad7d951 100644
--- a/src/3rdparty/pcre2/qt_attribution.json
+++ b/src/3rdparty/pcre2/qt_attribution.json
@@ -3,37 +3,38 @@
"Id": "pcre2",
"Name": "PCRE2",
"QDocModule": "qtcore",
- "QtUsage": "Optionally used in Qt Core (QRegularExpression). Configure with -system-pcre or -no-pcre to avoid.",
+ "QtUsage": "Used in Qt Core (QRegularExpression).",
"SecurityCritical": true,
"Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.",
"Homepage": "http://www.pcre.org/",
- "Version": "10.46",
- "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.46/pcre2-10.46.tar.bz2",
+ "Version": "10.47",
+ "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.47/pcre2-10.47.tar.bz2",
"PURL": "pkg:github/PCRE2Project/pcre2@pcre2-$<VERSION>",
"CPE": "cpe:2.3:a:pcre:pcre2:$<VERSION>:*:*:*:*:*:*:*",
"License": "BSD 3-clause \"New\" or \"Revised\" License with PCRE2 binary-like Packages Exception",
"LicenseId": "LicenseRef-BSD-3-Clause-with-PCRE2-Binary-Like-Packages-Exception",
"LicenseFile": "LICENCE.md",
- "Copyright": ["Copyright (c) 1997-2024 University of Cambridge",
+ "Copyright": ["Copyright (c) 1997-2007 University of Cambridge",
+ "Copyright (c) 2007-2024 Philip Hazel",
"Copyright (c) 2010-2024 Zoltan Herczeg"]
},
{
"Id": "pcre2-sljit",
"Name": "PCRE2 - Stack-less Just-In-Time Compiler",
"QDocModule": "qtcore",
- "QtUsage": "Optionally used in Qt Core (QRegularExpression). Configure with -system-pcre or -no-pcre to avoid.",
+ "QtUsage": "Used in Qt Core (QRegularExpression).",
"Path": "deps/sljit",
"Description": "The PCRE library is a set of functions that implement regular expression pattern matching using the same syntax and semantics as Perl 5.",
"Homepage": "http://www.pcre.org/",
- "Version": "10.46",
- "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.46/pcre2-10.46.tar.bz2",
+ "Version": "10.47",
+ "DownloadLocation": "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.47/pcre2-10.47.tar.bz2",
"PURL": "pkg:github/PCRE2Project/pcre2@$<VERSION>",
"CPE": "cpe:2.3:a:pcre:pcre2:$<VERSION>:*:*:*:*:*:*:*",
"License": "BSD 2-clause \"Simplified\" License",
"LicenseId": "BSD-2-Clause",
- "LicenseFile": "LICENCE-SLJIT",
- "Copyright": "Copyright (c) 2009-2024 Zoltan Herczeg"
+ "LicenseFile": "LICENSE-SLJIT",
+ "Copyright": "Copyright Zoltan Herczeg"
}
]
diff --git a/src/3rdparty/pcre2/src/pcre2.h b/src/3rdparty/pcre2/src/pcre2.h
index a6c739fb918..4034e5a91d4 100644
--- a/src/3rdparty/pcre2/src/pcre2.h
+++ b/src/3rdparty/pcre2/src/pcre2.h
@@ -42,25 +42,21 @@ POSSIBILITY OF SUCH DAMAGE.
/* The current PCRE version information. */
#define PCRE2_MAJOR 10
-#define PCRE2_MINOR 46
+#define PCRE2_MINOR 47
#define PCRE2_PRERELEASE
-#define PCRE2_DATE 2025-08-27
+#define PCRE2_DATE 2025-10-21
-/* When an application links to a PCRE DLL in Windows, the symbols that are
+/* When an application links to a PCRE2 DLL in Windows, the symbols that are
imported have to be identified as such. When building PCRE2, the appropriate
-export setting is defined in pcre2_internal.h, which includes this file. So we
-don't change existing definitions of PCRE2_EXP_DECL. */
+export setting is defined in pcre2_internal.h, which includes this file. So, we
+don't change existing definitions of PCRE2_EXP_DECL.
-#if defined(_WIN32) && !defined(PCRE2_STATIC)
-# ifndef PCRE2_EXP_DECL
-# define PCRE2_EXP_DECL extern __declspec(dllimport)
-# endif
-#endif
-
-/* By default, we use the standard "extern" declarations. */
+By default, we use the standard "extern" declarations. */
#ifndef PCRE2_EXP_DECL
-# ifdef __cplusplus
+# if defined(_WIN32) && !defined(PCRE2_STATIC)
+# define PCRE2_EXP_DECL extern __declspec(dllimport)
+# elif defined __cplusplus
# define PCRE2_EXP_DECL extern "C"
# else
# define PCRE2_EXP_DECL extern
@@ -68,14 +64,15 @@ don't change existing definitions of PCRE2_EXP_DECL. */
#endif
/* When compiling with the MSVC compiler, it is sometimes necessary to include
-a "calling convention" before exported function names. (This is secondhand
-information; I know nothing about MSVC myself). For example, something like
+a "calling convention" before exported function names. For example:
void __cdecl function(....)
-might be needed. In order so make this easy, all the exported functions have
-PCRE2_CALL_CONVENTION just before their names. It is rarely needed; if not
-set, we ensure here that it has no effect. */
+might be needed. In order to make this easy, all the exported functions have
+PCRE2_CALL_CONVENTION just before their names.
+
+PCRE2 normally uses the platform's standard calling convention, so this should
+not be set unless you know you need it. */
#ifndef PCRE2_CALL_CONVENTION
#define PCRE2_CALL_CONVENTION
@@ -343,6 +340,10 @@ pcre2_pattern_convert(). */
#define PCRE2_ERROR_PERL_ECLASS_EMPTY_EXPR 214
#define PCRE2_ERROR_PERL_ECLASS_MISSING_CLOSE 215
#define PCRE2_ERROR_PERL_ECLASS_UNEXPECTED_CHAR 216
+#define PCRE2_ERROR_EXPECTED_CAPTURE_GROUP 217
+#define PCRE2_ERROR_MISSING_OPENING_PARENTHESIS 218
+#define PCRE2_ERROR_MISSING_NUMBER_TERMINATOR 219
+#define PCRE2_ERROR_NULL_ERROROFFSET 220
/* "Expected" matching error codes: no match and partial match. */
@@ -432,6 +433,11 @@ released, the numbers must not be changed. */
#define PCRE2_ERROR_JIT_UNSUPPORTED (-68)
#define PCRE2_ERROR_REPLACECASE (-69)
#define PCRE2_ERROR_TOOLARGEREPLACE (-70)
+#define PCRE2_ERROR_DIFFSUBSPATTERN (-71)
+#define PCRE2_ERROR_DIFFSUBSSUBJECT (-72)
+#define PCRE2_ERROR_DIFFSUBSOFFSET (-73)
+#define PCRE2_ERROR_DIFFSUBSOPTIONS (-74)
+#define PCRE2_ERROR_BAD_BACKSLASH_K (-75)
/* Request types for pcre2_pattern_info() */
@@ -484,6 +490,7 @@ released, the numbers must not be changed. */
#define PCRE2_CONFIG_NEVER_BACKSLASH_C 13
#define PCRE2_CONFIG_COMPILED_WIDTHS 14
#define PCRE2_CONFIG_TABLES_LENGTH 15
+#define PCRE2_CONFIG_EFFECTIVE_LINKSIZE 16
/* Optimization directives for pcre2_set_optimize().
For binary compatibility, only add to this list; do not renumber. */
@@ -743,14 +750,14 @@ PCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \
PCRE2_EXP_DECL pcre2_match_data *PCRE2_CALL_CONVENTION \
pcre2_match_data_create_from_pattern(const pcre2_code *, \
pcre2_general_context *); \
+PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
+ pcre2_match_data_free(pcre2_match_data *); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_dfa_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
uint32_t, pcre2_match_data *, pcre2_match_context *, int *, PCRE2_SIZE); \
PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
pcre2_match(const pcre2_code *, PCRE2_SPTR, PCRE2_SIZE, PCRE2_SIZE, \
uint32_t, pcre2_match_data *, pcre2_match_context *); \
-PCRE2_EXP_DECL void PCRE2_CALL_CONVENTION \
- pcre2_match_data_free(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SPTR PCRE2_CALL_CONVENTION \
pcre2_get_mark(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
@@ -762,7 +769,9 @@ PCRE2_EXP_DECL uint32_t PCRE2_CALL_CONVENTION \
PCRE2_EXP_DECL PCRE2_SIZE *PCRE2_CALL_CONVENTION \
pcre2_get_ovector_pointer(pcre2_match_data *); \
PCRE2_EXP_DECL PCRE2_SIZE PCRE2_CALL_CONVENTION \
- pcre2_get_startchar(pcre2_match_data *);
+ pcre2_get_startchar(pcre2_match_data *); \
+PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \
+ pcre2_next_match(pcre2_match_data *, PCRE2_SIZE *, uint32_t *);
/* Convenience functions for handling matched substrings. */
@@ -942,6 +951,7 @@ pcre2_compile are called by application code. */
#define pcre2_match_data_create PCRE2_SUFFIX(pcre2_match_data_create_)
#define pcre2_match_data_create_from_pattern PCRE2_SUFFIX(pcre2_match_data_create_from_pattern_)
#define pcre2_match_data_free PCRE2_SUFFIX(pcre2_match_data_free_)
+#define pcre2_next_match PCRE2_SUFFIX(pcre2_next_match_)
#define pcre2_pattern_convert PCRE2_SUFFIX(pcre2_pattern_convert_)
#define pcre2_pattern_info PCRE2_SUFFIX(pcre2_pattern_info_)
#define pcre2_serialize_decode PCRE2_SUFFIX(pcre2_serialize_decode_)
diff --git a/src/3rdparty/pcre2/src/pcre2_auto_possess.c b/src/3rdparty/pcre2/src/pcre2_auto_possess.c
index 6d7f27b6904..408803246ac 100644
--- a/src/3rdparty/pcre2/src/pcre2_auto_possess.c
+++ b/src/3rdparty/pcre2/src/pcre2_auto_possess.c
@@ -38,16 +38,14 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains functions that scan a compiled pattern and change
repeats into possessive repeats where possible. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "pcre2_internal.h"
-#include "pcre2_internal.h"
/* This macro represents the max size of list[] and that is used to keep
track of UCD info in several places, it should be kept on sync with the
@@ -264,8 +262,10 @@ switch(ptype)
if (c < *p) return !negated;
if (c == *p++) return negated;
}
+ /* LCOV_EXCL_START */
PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */
break;
+ /* LCOV_EXCL_STOP */
/* Haven't yet thought these through. */
@@ -806,21 +806,21 @@ for(;;)
case OP_NOT_DIGIT:
invert_bits = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_DIGIT:
set2 = (const uint8_t *)(cb->cbits + cbit_digit);
break;
case OP_NOT_WHITESPACE:
invert_bits = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_WHITESPACE:
set2 = (const uint8_t *)(cb->cbits + cbit_space);
break;
case OP_NOT_WORDCHAR:
invert_bits = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_WORDCHAR:
set2 = (const uint8_t *)(cb->cbits + cbit_word);
break;
@@ -1103,7 +1103,7 @@ for(;;)
case OP_NCLASS:
if (chr > 255) return FALSE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CLASS:
if (chr > 255) break;
@@ -1141,8 +1141,10 @@ for(;;)
if (list[1] == 0) return TRUE;
}
+/* LCOV_EXCL_START */
PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */
return FALSE; /* Avoid compiler warnings */
+/* LCOV_EXCL_STOP */
}
@@ -1181,11 +1183,13 @@ for (;;)
{
c = *code;
+ /* LCOV_EXCL_START */
if (c >= OP_TABLE_LENGTH)
{
PCRE2_DEBUG_UNREACHABLE();
return -1; /* Something gone wrong */
}
+ /* LCOV_EXCL_STOP */
if (c >= OP_STAR && c <= OP_TYPEPOSUPTO)
{
diff --git a/src/3rdparty/pcre2/src/pcre2_chartables.c b/src/3rdparty/pcre2/src/pcre2_chartables.c
index 7362c3f2345..29f9200010c 100644
--- a/src/3rdparty/pcre2/src/pcre2_chartables.c
+++ b/src/3rdparty/pcre2/src/pcre2_chartables.c
@@ -19,10 +19,6 @@ PCRE2 is configured with --enable-rebuild-chartables. However, you can run
pcre2_dftables manually with the -L option to build tables using the LC_ALL
locale. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
const uint8_t PRIV(default_tables)[] = {
diff --git a/src/3rdparty/pcre2/src/pcre2_chkdint.c b/src/3rdparty/pcre2/src/pcre2_chkdint.c
index 70830236999..7aeb6405743 100644
--- a/src/3rdparty/pcre2/src/pcre2_chkdint.c
+++ b/src/3rdparty/pcre2/src/pcre2_chkdint.c
@@ -37,16 +37,16 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This file contains functions to implement checked integer operation */
-#ifndef PCRE2_PCRE2TEST
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#ifndef PCRE2_PCRE2TEST
#include "pcre2_internal.h"
#endif
+
+
/*************************************************
* Checked Integer Multiplication *
*************************************************/
diff --git a/src/3rdparty/pcre2/src/pcre2_compile.c b/src/3rdparty/pcre2/src/pcre2_compile.c
index 0ffac8939cb..f126e41b7b0 100644
--- a/src/3rdparty/pcre2/src/pcre2_compile.c
+++ b/src/3rdparty/pcre2/src/pcre2_compile.c
@@ -39,16 +39,14 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "pcre2_compile.h"
+
+
#define NLBLOCK cb /* Block containing newline information */
#define PSSTART start_pattern /* Field containing processed string start */
#define PSEND end_pattern /* Field containing processed string end */
-#include "pcre2_compile.h"
-
/* In rare error cases debugging might require calling pcre2_printint(). */
#if 0
@@ -57,7 +55,15 @@ POSSIBILITY OF SUCH DAMAGE.
#else
#define PRINTABLE(c) ((c) >= 32 && (c) < 127)
#endif
-#include "pcre2_printint.c"
+#define CHAR_OUTPUT(c) (c)
+#define CHAR_OUTPUT_HEX(c) (c)
+#define CHAR_INPUT(c) (c)
+#define CHAR_INPUT_HEX(c) (c)
+#include "pcre2_printint_inc.h"
+#undef PRINTABLE
+#undef CHAR_OUTPUT
+#undef CHAR_OUTPUT_HEX
+#undef CHAR_INPUT
#define DEBUG_CALL_PRINTINT
#endif
@@ -84,30 +90,6 @@ by defining macros in order to minimize #if usage. */
#endif
#endif
-/* Macros to store and retrieve a PCRE2_SIZE value in the parsed pattern, which
-consists of uint32_t elements. Assume that if uint32_t can't hold it, two of
-them will be able to (i.e. assume a 64-bit world). */
-
-#if PCRE2_SIZE_MAX <= UINT32_MAX
-#define PUTOFFSET(s,p) *p++ = s
-#define GETOFFSET(s,p) s = *p++
-#define GETPLUSOFFSET(s,p) s = *(++p)
-#define READPLUSOFFSET(s,p) s = p[1]
-#define SKIPOFFSET(p) p++
-#define SIZEOFFSET 1
-#else
-#define PUTOFFSET(s,p) \
- { *p++ = (uint32_t)(s >> 32); *p++ = (uint32_t)(s & 0xffffffff); }
-#define GETOFFSET(s,p) \
- { s = ((PCRE2_SIZE)p[0] << 32) | (PCRE2_SIZE)p[1]; p += 2; }
-#define GETPLUSOFFSET(s,p) \
- { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; p += 2; }
-#define READPLUSOFFSET(s,p) \
- { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; }
-#define SKIPOFFSET(p) p += 2
-#define SIZEOFFSET 2
-#endif
-
/* Function definitions to allow mutual recursion */
static int
@@ -216,8 +198,8 @@ static unsigned char meta_extra_lengths[] = {
3, /* META_COND_VERSION */
SIZEOFFSET, /* META_OFFSET */
0, /* META_SCS */
- 1, /* META_SCS_NAME */
- 1, /* META_SCS_NUMBER */
+ 1, /* META_CAPTURE_NAME */
+ 1, /* META_CAPTURE_NUMBER */
0, /* META_DOLLAR */
0, /* META_DOT */
0, /* META_ESCAPE - one more for ESC_P and ESC_p */
@@ -400,10 +382,10 @@ static const short int escapes[] = {
/* 4 */ 0, /* 5 */ 0,
/* 6 */ 0, /* 7 */ 0,
/* 8 */ 0, /* 9 */ 0,
- /* : */ CHAR_COLON, /* ; */ CHAR_SEMICOLON,
- /* < */ CHAR_LESS_THAN_SIGN, /* = */ CHAR_EQUALS_SIGN,
- /* > */ CHAR_GREATER_THAN_SIGN, /* ? */ CHAR_QUESTION_MARK,
- /* @ */ CHAR_COMMERCIAL_AT, /* A */ -ESC_A,
+ /* : */ ESCAPES_FIRST+0x0a, /* ; */ ESCAPES_FIRST+0x0b,
+ /* < */ ESCAPES_FIRST+0x0c, /* = */ ESCAPES_FIRST+0x0d,
+ /* > */ ESCAPES_FIRST+0x0e, /* ? */ ESCAPES_FIRST+0x0f,
+ /* @ */ ESCAPES_FIRST+0x10, /* A */ -ESC_A,
/* B */ -ESC_B, /* C */ -ESC_C,
/* D */ -ESC_D, /* E */ -ESC_E,
/* F */ 0, /* G */ -ESC_G,
@@ -416,10 +398,10 @@ static const short int escapes[] = {
/* T */ 0, /* U */ 0,
/* V */ -ESC_V, /* W */ -ESC_W,
/* X */ -ESC_X, /* Y */ 0,
- /* Z */ -ESC_Z, /* [ */ CHAR_LEFT_SQUARE_BRACKET,
- /* \ */ CHAR_BACKSLASH, /* ] */ CHAR_RIGHT_SQUARE_BRACKET,
- /* ^ */ CHAR_CIRCUMFLEX_ACCENT, /* _ */ CHAR_UNDERSCORE,
- /* ` */ CHAR_GRAVE_ACCENT, /* a */ CHAR_BEL,
+ /* Z */ -ESC_Z, /* [ */ ESCAPES_FIRST+0x2b,
+ /* \ */ ESCAPES_FIRST+0x2c, /* ] */ ESCAPES_FIRST+0x2d,
+ /* ^ */ ESCAPES_FIRST+0x2e, /* _ */ ESCAPES_FIRST+0x2f,
+ /* ` */ ESCAPES_FIRST+0x30, /* a */ CHAR_BEL,
/* b */ -ESC_b, /* c */ 0,
/* d */ -ESC_d, /* e */ CHAR_ESC,
/* f */ CHAR_FF, /* g */ 0,
@@ -438,43 +420,94 @@ static const short int escapes[] = {
#else
/* This is the "abnormal" table for EBCDIC systems without UTF-8 support.
-It runs from 'a' to '9'. For some minimal testing of EBCDIC features, the code
-is sometimes compiled on an ASCII system. In this case, we must not use CHAR_a
-because it is defined as 'a', which of course picks up the ASCII value. */
+It runs from 'a' to '9'. Our EBCDIC support can be provided via the compiler,
+which can interpret character literals like 'a' or '[' in an EBCDIC codepage;
+in this case, there is wide variance between codepages on the interpretation of
+characters between the letters ('[' and '{' and so on are placed in all sorts of
+different positions in the table). Thankfully however, all EBCDIC codepages
+place the letters and digits in the same location, so we hardcode that here.
+Our EBCDIC support can also be provided via numeric literals instead of
+character literals, so either way, 'CHAR_a' will be 0x81 when PCRE2 is compiled
+in EBCDIC mode. */
-#if 'a' == 0x81 /* Check for a real EBCDIC environment */
#define ESCAPES_FIRST CHAR_a
#define ESCAPES_LAST CHAR_9
#define UPPER_CASE(c) (c+64)
-#else /* Testing in an ASCII environment */
-#define ESCAPES_FIRST ((unsigned char)'\x81') /* EBCDIC 'a' */
-#define ESCAPES_LAST ((unsigned char)'\xf9') /* EBCDIC '9' */
-#define UPPER_CASE(c) (c-32)
-#endif
static const short int escapes[] = {
-/* 80 */ CHAR_BEL, -ESC_b, 0, -ESC_d, CHAR_ESC, CHAR_FF, 0,
-/* 88 */ -ESC_h, 0, 0, '{', 0, 0, 0, 0,
-/* 90 */ 0, 0, -ESC_k, 0, 0, CHAR_LF, 0, -ESC_p,
-/* 98 */ 0, CHAR_CR, 0, '}', 0, 0, 0, 0,
-/* A0 */ 0, '~', -ESC_s, CHAR_HT, 0, -ESC_v, -ESC_w, 0,
-/* A8 */ 0, -ESC_z, 0, 0, 0, '[', 0, 0,
-/* B0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* B8 */ 0, 0, 0, 0, 0, ']', '=', '-',
-/* C0 */ '{', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G,
-/* C8 */ -ESC_H, 0, 0, 0, 0, 0, 0, 0,
-/* D0 */ '}', 0, -ESC_K, 0, 0, -ESC_N, 0, -ESC_P,
-/* D8 */ -ESC_Q, -ESC_R, 0, 0, 0, 0, 0, 0,
-/* E0 */ '\\', 0, -ESC_S, 0, 0, -ESC_V, -ESC_W, -ESC_X,
-/* E8 */ 0, -ESC_Z, 0, 0, 0, 0, 0, 0,
-/* F0 */ 0, 0, 0, 0, 0, 0, 0, 0,
-/* F8 */ 0, 0
+ /* 0x81 a */ CHAR_BEL, /* 0x82 b */ -ESC_b,
+ /* 0x83 c */ 0, /* 0x84 d */ -ESC_d,
+ /* 0x85 e */ CHAR_ESC, /* 0x86 f */ CHAR_FF,
+ /* 0x87 g */ 0, /* 0x88 h */ -ESC_h,
+ /* 0x89 i */ 0, /* 0x8a */ ESCAPES_FIRST+0x09,
+ /* 0x8b */ ESCAPES_FIRST+0x0a, /* 0x8c */ ESCAPES_FIRST+0x0b,
+ /* 0x8d */ ESCAPES_FIRST+0x0c, /* 0x8e */ ESCAPES_FIRST+0x0d,
+ /* 0x8f */ ESCAPES_FIRST+0x0e, /* 0x90 */ ESCAPES_FIRST+0x0f,
+ /* 0x91 j */ 0, /* 0x92 k */ -ESC_k,
+ /* 0x93 l */ 0, /* 0x94 m */ 0,
+ /* 0x95 n */ CHAR_LF, /* 0x96 o */ 0,
+ /* 0x97 p */ -ESC_p, /* 0x98 q */ 0,
+ /* 0x99 r */ CHAR_CR, /* 0x9a */ ESCAPES_FIRST+0x19,
+ /* 0x9b */ ESCAPES_FIRST+0x1a, /* 0x9c */ ESCAPES_FIRST+0x1b,
+ /* 0x9d */ ESCAPES_FIRST+0x1c, /* 0x9e */ ESCAPES_FIRST+0x1d,
+ /* 0x9f */ ESCAPES_FIRST+0x1e, /* 0xa0 */ ESCAPES_FIRST+0x1f,
+ /* 0xa1 */ ESCAPES_FIRST+0x20, /* 0xa2 s */ -ESC_s,
+ /* 0xa3 t */ CHAR_HT, /* 0xa4 u */ 0,
+ /* 0xa5 v */ -ESC_v, /* 0xa6 w */ -ESC_w,
+ /* 0xa7 x */ 0, /* 0xa8 y */ 0,
+ /* 0xa9 z */ -ESC_z, /* 0xaa */ ESCAPES_FIRST+0x29,
+ /* 0xab */ ESCAPES_FIRST+0x2a, /* 0xac */ ESCAPES_FIRST+0x2b,
+ /* 0xad */ ESCAPES_FIRST+0x2c, /* 0xae */ ESCAPES_FIRST+0x2d,
+ /* 0xaf */ ESCAPES_FIRST+0x2e, /* 0xb0 */ ESCAPES_FIRST+0x2f,
+ /* 0xb1 */ ESCAPES_FIRST+0x30, /* 0xb2 */ ESCAPES_FIRST+0x31,
+ /* 0xb3 */ ESCAPES_FIRST+0x32, /* 0xb4 */ ESCAPES_FIRST+0x33,
+ /* 0xb5 */ ESCAPES_FIRST+0x34, /* 0xb6 */ ESCAPES_FIRST+0x35,
+ /* 0xb7 */ ESCAPES_FIRST+0x36, /* 0xb8 */ ESCAPES_FIRST+0x37,
+ /* 0xb9 */ ESCAPES_FIRST+0x38, /* 0xba */ ESCAPES_FIRST+0x39,
+ /* 0xbb */ ESCAPES_FIRST+0x3a, /* 0xbc */ ESCAPES_FIRST+0x3b,
+ /* 0xbd */ ESCAPES_FIRST+0x3c, /* 0xbe */ ESCAPES_FIRST+0x3d,
+ /* 0xbf */ ESCAPES_FIRST+0x3e, /* 0xc0 */ ESCAPES_FIRST+0x3f,
+ /* 0xc1 A */ -ESC_A, /* 0xc2 B */ -ESC_B,
+ /* 0xc3 C */ -ESC_C, /* 0xc4 D */ -ESC_D,
+ /* 0xc5 E */ -ESC_E, /* 0xc6 F */ 0,
+ /* 0xc7 G */ -ESC_G, /* 0xc8 H */ -ESC_H,
+ /* 0xc9 I */ 0, /* 0xca */ ESCAPES_FIRST+0x49,
+ /* 0xcb */ ESCAPES_FIRST+0x4a, /* 0xcc */ ESCAPES_FIRST+0x4b,
+ /* 0xcd */ ESCAPES_FIRST+0x4c, /* 0xce */ ESCAPES_FIRST+0x4d,
+ /* 0xcf */ ESCAPES_FIRST+0x4e, /* 0xd0 */ ESCAPES_FIRST+0x4f,
+ /* 0xd1 J */ 0, /* 0xd2 K */ -ESC_K,
+ /* 0xd3 L */ 0, /* 0xd4 M */ 0,
+ /* 0xd5 N */ -ESC_N, /* 0xd6 O */ 0,
+ /* 0xd7 P */ -ESC_P, /* 0xd8 Q */ -ESC_Q,
+ /* 0xd9 R */ -ESC_R, /* 0xda */ ESCAPES_FIRST+0x59,
+ /* 0xdb */ ESCAPES_FIRST+0x5a, /* 0xdc */ ESCAPES_FIRST+0x5b,
+ /* 0xdd */ ESCAPES_FIRST+0x5c, /* 0xde */ ESCAPES_FIRST+0x5d,
+ /* 0xdf */ ESCAPES_FIRST+0x5e, /* 0xe0 */ ESCAPES_FIRST+0x5f,
+ /* 0xe1 */ ESCAPES_FIRST+0x60, /* 0xe2 S */ -ESC_S,
+ /* 0xe3 T */ 0, /* 0xe4 U */ 0,
+ /* 0xe5 V */ -ESC_V, /* 0xe6 W */ -ESC_W,
+ /* 0xe7 X */ -ESC_X, /* 0xe8 Y */ 0,
+ /* 0xe9 Z */ -ESC_Z, /* 0xea */ ESCAPES_FIRST+0x69,
+ /* 0xeb */ ESCAPES_FIRST+0x6a, /* 0xec */ ESCAPES_FIRST+0x6b,
+ /* 0xed */ ESCAPES_FIRST+0x6c, /* 0xee */ ESCAPES_FIRST+0x6d,
+ /* 0xef */ ESCAPES_FIRST+0x6e, /* 0xf0 0 */ 0,
+ /* 0xf1 1 */ 0, /* 0xf2 2 */ 0,
+ /* 0xf3 3 */ 0, /* 0xf4 4 */ 0,
+ /* 0xf5 5 */ 0, /* 0xf6 6 */ 0,
+ /* 0xf7 7 */ 0, /* 0xf8 8 */ 0,
+ /* 0xf9 9 */ 0,
};
/* We also need a table of characters that may follow \c in an EBCDIC
environment for characters 0-31. */
-static unsigned char ebcdic_escape_c[] = "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_";
+static unsigned char ebcdic_escape_c[] = {
+ CHAR_COMMERCIAL_AT, CHAR_A, CHAR_B, CHAR_C, CHAR_D, CHAR_E, CHAR_F, CHAR_G,
+ CHAR_H, CHAR_I, CHAR_J, CHAR_K, CHAR_L, CHAR_M, CHAR_N, CHAR_O, CHAR_P,
+ CHAR_Q, CHAR_R, CHAR_S, CHAR_T, CHAR_U, CHAR_V, CHAR_W, CHAR_X, CHAR_Y,
+ CHAR_Z, CHAR_LEFT_SQUARE_BRACKET, CHAR_BACKSLASH, CHAR_RIGHT_SQUARE_BRACKET,
+ CHAR_CIRCUMFLEX_ACCENT, CHAR_UNDERSCORE
+};
#endif /* EBCDIC */
@@ -1037,12 +1070,12 @@ for (;;)
fprintf(stderr, "META (*scan_substring:");
break;
- case META_SCS_NAME:
- fprintf(stderr, "META_SCS_NAME length=%d relative_offset=%d", *pptr++, (int)meta_arg);
+ case META_CAPTURE_NAME:
+ fprintf(stderr, "META_CAPTURE_NAME length=%d relative_offset=%d", *pptr++, (int)meta_arg);
break;
- case META_SCS_NUMBER:
- fprintf(stderr, "META_SCS_NUMBER %d relative_offset=%d", *pptr++, (int)meta_arg);
+ case META_CAPTURE_NUMBER:
+ fprintf(stderr, "META_CAPTURE_NUMBER %d relative_offset=%d", *pptr++, (int)meta_arg);
break;
case META_MARK:
@@ -1533,6 +1566,13 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0)
goto COME_FROM_NU;
}
#endif
+
+ /* Improve error offset. */
+ ptr = p + 2;
+ while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++;
+ while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;
+ if (ptr < ptrend && *ptr == CHAR_RIGHT_CURLY_BRACKET) ptr++;
+
*errorcodeptr = ERR93;
}
@@ -1541,6 +1581,7 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0)
else if (isclass || cb == NULL)
{
+ ptr++; /* Skip over the opening brace */
*errorcodeptr = ERR37;
}
@@ -1551,7 +1592,10 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0)
{
if (!read_repeat_counts(&p, ptrend, NULL, NULL, errorcodeptr) &&
*errorcodeptr == 0)
+ {
+ ptr++; /* Skip over the opening brace */
*errorcodeptr = ERR37;
+ }
}
}
}
@@ -1572,11 +1616,11 @@ else
if (cb == NULL)
{
- if (c < CHAR_0 ||
- (c > CHAR_9 && (c != CHAR_c && c != CHAR_o && c != CHAR_x && c != CHAR_g)))
+ if (!(c >= CHAR_0 && c <= CHAR_9) && c != CHAR_c && c != CHAR_o &&
+ c != CHAR_x && c != CHAR_g)
{
*errorcodeptr = ERR3;
- return 0;
+ goto EXIT;
}
alt_bsux = FALSE; /* Do not modify \x handling */
}
@@ -1601,7 +1645,9 @@ else
because otherwise \u{ 12} (for example) would be treated as u{12}. */
case CHAR_u:
- if (!alt_bsux) *errorcodeptr = ERR37; else
+ if (!alt_bsux)
+ *errorcodeptr = ERR37;
+ else
{
uint32_t xc;
@@ -1727,8 +1773,8 @@ else
if (p >= ptrend || *p != CHAR_GREATER_THAN_SIGN)
{
- /* not advancing ptr; report error at the \g character */
- *errorcodeptr = ERR57;
+ ptr = p;
+ *errorcodeptr = ERR119; /* Missing terminator for number */
break;
}
@@ -1764,8 +1810,8 @@ else
if (p >= ptrend || *p != CHAR_RIGHT_CURLY_BRACKET)
{
- /* not advancing ptr; report error at the \g character */
- *errorcodeptr = ERR57;
+ ptr = p;
+ *errorcodeptr = ERR119; /* Missing terminator for number */
break;
}
ptr = p + 1;
@@ -1890,7 +1936,7 @@ else
if (c >= CHAR_8) break;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* \0 always starts an octal number, but we may drop through to here with a
larger first octal digit. The original code used just to take the least
@@ -1922,12 +1968,12 @@ else
with optional spaces or tabs after { and before }. */
case CHAR_o:
- if (ptr >= ptrend || *ptr++ != CHAR_LEFT_CURLY_BRACKET)
+ if (ptr >= ptrend || *ptr != CHAR_LEFT_CURLY_BRACKET)
{
- ptr--;
*errorcodeptr = ERR55;
break;
}
+ ptr++;
while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;
if (ptr >= ptrend || *ptr == CHAR_RIGHT_CURLY_BRACKET)
@@ -1962,19 +2008,19 @@ else
while (ptr < ptrend && *ptr >= CHAR_0 && *ptr <= CHAR_7) ptr++;
*errorcodeptr = ERR34;
}
- else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
+ else if (utf && c >= 0xd800 && c <= 0xdfff &&
+ (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
{
- if (utf && c >= 0xd800 && c <= 0xdfff &&
- (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
- {
- ptr--;
- *errorcodeptr = ERR73;
- }
+ *errorcodeptr = ERR73;
+ }
+ else if (ptr < ptrend && *ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ ptr++;
}
else
{
- ptr--;
*errorcodeptr = ERR64;
+ goto ESCAPE_FAILED_FORWARD;
}
break;
@@ -2043,14 +2089,14 @@ else
while (ptr < ptrend && XDIGIT(*ptr) != 0xff) ptr++;
*errorcodeptr = ERR34;
}
- else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET)
+ else if (utf && c >= 0xd800 && c <= 0xdfff &&
+ (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
{
- if (utf && c >= 0xd800 && c <= 0xdfff &&
- (xoptions & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)
- {
- ptr--;
- *errorcodeptr = ERR73;
- }
+ *errorcodeptr = ERR73;
+ }
+ else if (ptr < ptrend && *ptr == CHAR_RIGHT_CURLY_BRACKET)
+ {
+ ptr++;
}
/* If the sequence of hex digits (followed by optional space) does not
@@ -2060,8 +2106,8 @@ else
else
{
- ptr--;
*errorcodeptr = ERR67;
+ goto ESCAPE_FAILED_FORWARD;
}
} /* End of \x{} processing */
@@ -2113,11 +2159,7 @@ else
For testing the EBCDIC handling of \c in an ASCII environment, recognize
the EBCDIC value of 'c' explicitly. */
-#if defined EBCDIC && 'a' != 0x81
- case 0x83:
-#else
case CHAR_c:
-#endif
if (ptr >= ptrend)
{
*errorcodeptr = ERR2;
@@ -2132,7 +2174,7 @@ else
if (c < 32 || c > 126) /* Excludes all non-printable ASCII */
{
*errorcodeptr = ERR68;
- break;
+ goto ESCAPE_FAILED_FORWARD;
}
c ^= 0x40;
@@ -2143,14 +2185,20 @@ else
#else
if (c == CHAR_QUESTION_MARK)
- c = ('\\' == 188 && '`' == 74)? 0x5f : 0xff;
+ c = (CHAR_BACKSLASH == 188 && CHAR_GRAVE_ACCENT == 74)? 0x5f : 0xff;
else
{
for (i = 0; i < 32; i++)
{
if (c == ebcdic_escape_c[i]) break;
}
- if (i < 32) c = i; else *errorcodeptr = ERR68;
+ if (i < 32)
+ c = i;
+ else
+ {
+ *errorcodeptr = ERR68;
+ goto ESCAPE_FAILED_FORWARD;
+ }
}
#endif /* EBCDIC */
@@ -2162,16 +2210,25 @@ else
default:
*errorcodeptr = ERR3;
- *ptrptr = ptr - 1; /* Point to the character at fault */
- return 0;
+ break;
}
}
/* Set the pointer to the next character before returning. */
+EXIT:
*ptrptr = ptr;
*chptr = c;
return escape;
+
+/* Some errors need to indicate the next character. */
+
+ESCAPE_FAILED_FORWARD:
+ptr++;
+#ifdef SUPPORT_UNICODE
+if (utf) FORWARDCHARTEST(ptr, ptrend);
+#endif
+goto EXIT;
}
@@ -2188,6 +2245,7 @@ after the final code unit of the escape sequence.
Arguments:
ptrptr the pattern position pointer
+ utf true if the input is UTF-encoded
negptr a boolean that is set TRUE for negation else FALSE
ptypeptr an unsigned int that is set to the type value
pdataptr an unsigned int that is set to the detailed property value
@@ -2198,18 +2256,23 @@ Returns: TRUE if the type value was found, or FALSE for an invalid type
*/
static BOOL
-get_ucp(PCRE2_SPTR *ptrptr, BOOL *negptr, uint16_t *ptypeptr,
+get_ucp(PCRE2_SPTR *ptrptr, BOOL utf, BOOL *negptr, uint16_t *ptypeptr,
uint16_t *pdataptr, int *errorcodeptr, compile_block *cb)
{
-PCRE2_UCHAR c;
-PCRE2_SIZE i, bot, top;
+uint32_t c;
+ptrdiff_t i;
+PCRE2_SIZE bot, top;
PCRE2_SPTR ptr = *ptrptr;
PCRE2_UCHAR name[50];
PCRE2_UCHAR *vptr = NULL;
uint16_t ptscript = PT_NOTSCRIPT;
+#ifndef MAYBE_UTF_MULTI
+(void)utf; /* Avoid compiler warning */
+#endif
+
if (ptr >= cb->end_pattern) goto ERROR_RETURN;
-c = *ptr++;
+GETCHARINCTEST(c, ptr);
*negptr = FALSE;
/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
@@ -2230,15 +2293,14 @@ if (c == CHAR_LEFT_CURLY_BRACKET)
REDO:
if (ptr >= cb->end_pattern) goto ERROR_RETURN;
- c = *ptr++;
+ GETCHARINCTEST(c, ptr);
/* Skip ignorable Unicode characters. */
- while (c == CHAR_UNDERSCORE || c == CHAR_MINUS || c == CHAR_SPACE ||
- (c >= CHAR_HT && c <= CHAR_CR))
+ if (c == CHAR_UNDERSCORE || c == CHAR_MINUS || c == CHAR_SPACE ||
+ (c >= CHAR_HT && c <= CHAR_CR))
{
- if (ptr >= cb->end_pattern) goto ERROR_RETURN;
- c = *ptr++;
+ goto REDO;
}
/* The first significant character being circumflex negates the meaning of
@@ -2506,7 +2568,7 @@ return -1;
the name of a subpattern or a (*VERB) or an (*alpha_assertion). The initial
pointer must be to the preceding character. If that character is '*' we are
reading a verb or alpha assertion name. The pointer is updated to point after
-the name, for a VERB or alpha assertion name, or after tha name's terminator
+the name, for a VERB or alpha assertion name, or after the name's terminator
for a subpattern name. Returning both the offset and the name pointer is
redundant information, but some callers use one and some the other, so it is
simplest just to return both. When the name is in braces, spaces and tabs are
@@ -2559,12 +2621,14 @@ by Unicode properties, and underscores, but must not start with a digit. */
if (utf && is_group)
{
uint32_t c, type;
+ PCRE2_SPTR p = ptr;
- GETCHAR(c, ptr);
+ GETCHARINC(c, p); /* Peek at next character */
type = UCD_CHARTYPE(c);
if (type == ucp_Nd)
{
+ ptr = p;
*errorcodeptr = ERR44;
goto FAILED;
}
@@ -2573,10 +2637,9 @@ if (utf && is_group)
{
if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L &&
c != CHAR_UNDERSCORE) break;
- ptr++;
- FORWARDCHARTEST(ptr, ptrend);
- if (ptr >= ptrend) break;
- GETCHAR(c, ptr);
+ ptr = p; /* Accept character and peek again */
+ if (p >= ptrend) break;
+ GETCHARINC(c, p);
type = UCD_CHARTYPE(c);
}
}
@@ -2592,6 +2655,7 @@ won't be recognized. */
{
if (is_group && IS_DIGIT(*ptr))
{
+ ++ptr;
*errorcodeptr = ERR44;
goto FAILED;
}
@@ -2604,7 +2668,7 @@ won't be recognized. */
/* Check name length */
-if (ptr > *nameptr + MAX_NAME_SIZE)
+if (ptr - *nameptr > MAX_NAME_SIZE)
{
*errorcodeptr = ERR48;
goto FAILED;
@@ -2623,12 +2687,15 @@ if (is_group)
}
if (is_braced)
while (ptr < ptrend && (*ptr == CHAR_SPACE || *ptr == CHAR_HT)) ptr++;
- if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator)
+ if (terminator != 0)
{
- *errorcodeptr = ERR42;
- goto FAILED;
+ if (ptr >= ptrend || *ptr != (PCRE2_UCHAR)terminator)
+ {
+ *errorcodeptr = ERR42;
+ goto FAILED;
+ }
+ ptr++;
}
- ptr++;
}
*ptrptr = ptr;
@@ -2641,6 +2708,128 @@ return FALSE;
+/**************************************************
+* Parse capturing bracket argument list *
+**************************************************/
+
+/* Reads a list of capture references. The references
+can be numbers or names.
+
+Arguments:
+ ptrptr points to the character pointer variable
+ ptrend points to the end of the input string
+ utf true if the input is UTF-encoded
+ parsed_pattern the parsed pattern pointer
+ offset last known offset
+ errcodeptr where to put an error code
+ cb pointer to the compile data block
+
+Returns: updated parsed_pattern pointer on success
+ NULL otherwise
+*/
+
+static uint32_t *
+parse_capture_list(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend,
+ BOOL utf, uint32_t *parsed_pattern, PCRE2_SIZE offset,
+ int *errorcodeptr, compile_block *cb)
+{
+PCRE2_SIZE next_offset;
+PCRE2_SPTR ptr = *ptrptr;
+PCRE2_SPTR name;
+PCRE2_UCHAR terminator;
+uint32_t meta, namelen;
+int i;
+
+if (ptr >= ptrend || *ptr != CHAR_LEFT_PARENTHESIS)
+ {
+ *errorcodeptr = ERR118;
+ goto FAILED;
+ }
+
+for (;;)
+ {
+ ptr++;
+ next_offset = (PCRE2_SIZE)(ptr - cb->start_pattern);
+
+ if (ptr >= ptrend)
+ {
+ *errorcodeptr = ERR117;
+ goto FAILED;
+ }
+
+ /* Handle [+-]number cases */
+ if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61,
+ &i, errorcodeptr))
+ {
+ PCRE2_ASSERT(i >= 0);
+ if (i <= 0)
+ {
+ *errorcodeptr = ERR15;
+ goto FAILED;
+ }
+ meta = META_CAPTURE_NUMBER;
+ namelen = (uint32_t)i;
+ }
+ else if (*errorcodeptr != 0) goto FAILED; /* Number too big */
+ else
+ {
+ /* Handle 'name' or <name> cases. */
+ if (*ptr == CHAR_LESS_THAN_SIGN)
+ terminator = CHAR_GREATER_THAN_SIGN;
+ else if (*ptr == CHAR_APOSTROPHE)
+ terminator = CHAR_APOSTROPHE;
+ else
+ {
+ *errorcodeptr = ERR117;
+ goto FAILED;
+ }
+
+ if (!read_name(&ptr, ptrend, utf, terminator, &next_offset,
+ &name, &namelen, errorcodeptr, cb)) goto FAILED;
+
+ meta = META_CAPTURE_NAME;
+ }
+
+ PCRE2_ASSERT(next_offset > 0);
+ if (offset == 0 || (next_offset - offset) >= 0x10000)
+ {
+ *parsed_pattern++ = META_OFFSET;
+ PUTOFFSET(next_offset, parsed_pattern);
+ offset = next_offset;
+ }
+
+ /* The offset is encoded as a relative offset, because for some
+ inputs such as ",2" in (1,2,3), we only have space for two uint32_t
+ values, and an opcode and absolute offset may require three uint32_t
+ values. */
+ *parsed_pattern++ = meta | (uint32_t)(next_offset - offset);
+ *parsed_pattern++ = namelen;
+ offset = next_offset;
+
+ if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+
+ if (*ptr == CHAR_RIGHT_PARENTHESIS) break;
+
+ if (*ptr != CHAR_COMMA)
+ {
+ *errorcodeptr = ERR24;
+ goto FAILED;
+ }
+ }
+
+*ptrptr = ptr + 1;
+return parsed_pattern;
+
+UNCLOSED_PARENTHESIS:
+*errorcodeptr = ERR14;
+
+FAILED:
+*ptrptr = ptr;
+return NULL;
+}
+
+
+
/*************************************************
* Manage callouts at start of cycle *
*************************************************/
@@ -2719,21 +2908,21 @@ switch(escape)
{
case ESC_D:
prop = ESC_P;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case ESC_d:
ascii_option = PCRE2_EXTRA_ASCII_BSD;
break;
case ESC_S:
prop = ESC_P;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case ESC_s:
ascii_option = PCRE2_EXTRA_ASCII_BSS;
break;
case ESC_W:
prop = ESC_P;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case ESC_w:
ascii_option = PCRE2_EXTRA_ASCII_BSW;
break;
@@ -2942,6 +3131,7 @@ uint32_t add_after_mark = 0;
uint16_t nest_depth = 0;
int16_t class_depth_m1 = -1; /* The m1 means minus 1. */
int16_t class_maxdepth_m1 = -1;
+uint16_t hash;
int after_manual_callout = 0;
int expect_cond_assert = 0;
int errorcode = 0;
@@ -2951,7 +3141,7 @@ BOOL inescq = FALSE;
BOOL inverbname = FALSE;
BOOL utf = (options & PCRE2_UTF) != 0;
BOOL auto_callout = (options & PCRE2_AUTO_CALLOUT) != 0;
-BOOL isdupname;
+BOOL is_dupname;
BOOL negate_class;
BOOL okquantifier = FALSE;
PCRE2_SPTR thisptr;
@@ -2996,12 +3186,15 @@ if ((options & PCRE2_LITERAL) != 0)
{
while (ptr < ptrend)
{
+ /* LCOV_EXCL_START */
if (parsed_pattern >= parsed_pattern_end)
{
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR63; /* Internal error (parsed pattern overflow) */
goto FAILED;
}
+ /* LCOV_EXCL_STOP */
+
thisptr = ptr;
GETCHARINCTEST(c, ptr);
if (auto_callout)
@@ -3067,6 +3260,7 @@ while (ptr < ptrend)
ptr_check = ptr;
#endif
+ /* LCOV_EXCL_START */
if (parsed_pattern >= parsed_pattern_end)
{
/* Weak pre-write check; only ensures parsed_pattern[0] is writeable
@@ -3075,6 +3269,7 @@ while (ptr < ptrend)
errorcode = ERR63; /* Internal error (parsed pattern overflow) */
goto FAILED;
}
+ /* LCOV_EXCL_STOP */
/* If the last time round this loop something was added, parsed_pattern will
no longer be equal to this_parsed_item. Remember where the previous item
@@ -3104,12 +3299,6 @@ while (ptr < ptrend)
}
else
{
- if (expect_cond_assert > 0) /* A literal is not allowed if we are */
- { /* expecting a conditional assertion, */
- ptr--; /* but an empty \Q\E sequence is OK. */
- errorcode = ERR28;
- goto FAILED;
- }
if (inverbname)
{ /* Don't use PARSED_LITERAL() because it */
#if PCRE2_CODE_UNIT_WIDTH == 32 /* sets okquantifier. */
@@ -3238,6 +3427,15 @@ while (ptr < ptrend)
{
if (*ptr == CHAR_Q || *ptr == CHAR_E)
{
+ /* A literal inside a \Q...\E is not allowed if we are expecting a
+ conditional assertion, but an empty \Q\E sequence is OK. */
+ if (expect_cond_assert > 0 && *ptr == CHAR_Q &&
+ !(ptrend - ptr >= 3 && ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E))
+ {
+ ptr--;
+ errorcode = ERR28;
+ goto FAILED;
+ }
inescq = *ptr == CHAR_Q;
ptr++;
continue;
@@ -3347,9 +3545,9 @@ while (ptr < ptrend)
if (!ok)
{
- ptr--; /* Adjust error offset */
errorcode = ERR28;
- goto FAILED;
+ if (expect_cond_assert == 2) goto FAILED;
+ goto FAILED_BACK;
}
}
@@ -3425,7 +3623,7 @@ while (ptr < ptrend)
else if (escape < 0)
{
- offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 1);
+ offset = (PCRE2_SIZE)(ptr - cb->start_pattern);
escape = -escape - 1;
*parsed_pattern++ = META_BACKREF | (uint32_t)escape;
if (escape < 10)
@@ -3523,7 +3721,7 @@ while (ptr < ptrend)
{
BOOL negated;
uint16_t ptype = 0, pdata = 0;
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
+ if (!get_ucp(&ptr, utf, &negated, &ptype, &pdata, &errorcode, cb))
goto ESCAPE_FAILED;
if (negated) escape = (escape == ESC_P)? ESC_p : ESC_P;
*parsed_pattern++ = META_ESCAPE + escape;
@@ -3565,10 +3763,11 @@ while (ptr < ptrend)
{
if (p >= ptrend || *p != terminator)
{
- errorcode = ERR57;
+ ptr = p;
+ errorcode = ERR119; /* Missing terminator for number */
goto ESCAPE_FAILED;
}
- ptr = p;
+ ptr = p + 1;
goto SET_RECURSION;
}
if (errorcode != 0) goto ESCAPE_FAILED;
@@ -3649,7 +3848,7 @@ while (ptr < ptrend)
if (!prev_okquantifier)
{
errorcode = ERR9;
- goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549
+ goto FAILED;
}
/* Most (*VERB)s are not allowed to be quantified, but an ungreedy
@@ -3738,6 +3937,7 @@ while (ptr < ptrend)
check_posix_syntax(ptr, ptrend, &tempptr))
{
errorcode = (*ptr-- == CHAR_COLON)? ERR12 : ERR13;
+ ptr = tempptr + 2;
goto FAILED;
}
@@ -3965,8 +4165,9 @@ while (ptr < ptrend)
/* Validate nesting depth */
if (class_depth_m1 >= ECLASS_NEST_LIMIT - 1)
{
- errorcode = ERR107;
- goto FAILED; /* Classes too deeply nested */
+ ptr--; /* Point rightwards at the paren, same as ERR19. */
+ errorcode = ERR107; /* Classes too deeply nested */
+ goto FAILED;
}
/* Process the character class start. If the first character is '^', set
@@ -4081,7 +4282,8 @@ while (ptr < ptrend)
if (c == CHAR_RIGHT_SQUARE_BRACKET && class_depth_m1 != 0)
{
errorcode = ERR14;
- goto FAILED_BACK;
+ ptr--; /* Correct the offset */
+ goto FAILED;
}
if (c == CHAR_RIGHT_PARENTHESIS && class_depth_m1 < 1)
{
@@ -4301,7 +4503,6 @@ while (ptr < ptrend)
case ESC_R:
case ESC_X:
errorcode = ERR7;
- ptr--; // TODO https://github.com/PCRE2Project/pcre2/issues/549
goto FAILED;
case ESC_N: /* Not permitted by Perl either */
@@ -4336,7 +4537,7 @@ while (ptr < ptrend)
{
BOOL negated;
uint16_t ptype = 0, pdata = 0;
- if (!get_ucp(&ptr, &negated, &ptype, &pdata, &errorcode, cb))
+ if (!get_ucp(&ptr, utf, &negated, &ptype, &pdata, &errorcode, cb))
goto FAILED;
/* In caseless matching, particular characteristics Lu, Ll, and Lt
@@ -4362,9 +4563,11 @@ while (ptr < ptrend)
/* All others are not allowed in a class */
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
+ /* LCOV_EXCL_STOP */
case ESC_A:
case ESC_Z:
@@ -4373,7 +4576,6 @@ while (ptr < ptrend)
case ESC_K:
case ESC_C:
errorcode = ERR7;
- ptr--; // TODO https://github.com/PCRE2Project/pcre2/issues/549
goto FAILED;
}
@@ -4464,7 +4666,7 @@ while (ptr < ptrend)
else if (parsed_pattern[-2] > c) /* Check range is in order */
{
errorcode = ERR8;
- goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549
+ goto FAILED;
}
else
{
@@ -4560,10 +4762,11 @@ while (ptr < ptrend)
vn = alasnames;
if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen,
&errorcode, cb)) goto FAILED;
- if (ptr >= ptrend || *ptr != CHAR_COLON)
+ if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
+ if (*ptr != CHAR_COLON)
{
errorcode = ERR95; /* Malformed */
- goto FAILED;
+ goto FAILED_FORWARD;
}
/* Scan the table of alpha assertion names */
@@ -4598,10 +4801,12 @@ while (ptr < ptrend)
switch(meta)
{
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR89; /* Unknown code; should never occur because */
goto FAILED; /* the meta values come from a table above. */
+ /* LCOV_EXCL_STOP */
case META_ATOMIC:
goto ATOMIC_GROUP;
@@ -4616,87 +4821,12 @@ while (ptr < ptrend)
goto NEGATIVE_LOOK_AHEAD;
case META_SCS:
- if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
-
- if (*ptr != CHAR_LEFT_PARENTHESIS)
- {
- errorcode = ERR15;
- goto FAILED;
- }
-
ptr++;
*parsed_pattern++ = META_SCS;
- /* Temporary variable, zero in the first iteration. */
- offset = 0;
-
- for (;;)
- {
- PCRE2_SIZE next_offset = (PCRE2_SIZE)(ptr - cb->start_pattern);
-
- /* Handle (scan_substring:([+-]number)... */
- if (read_number(&ptr, ptrend, cb->bracount, MAX_GROUP_NUMBER, ERR61,
- &i, &errorcode))
- {
- PCRE2_ASSERT(i >= 0);
- if (i <= 0)
- {
- errorcode = ERR15;
- goto FAILED;
- }
- meta = META_SCS_NUMBER;
- namelen = (uint32_t)i;
- }
- else if (errorcode != 0) goto FAILED; /* Number too big */
- else
- {
- if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
- /* Handle (*scan_substring:('name') or (*scan_substring:(<name>) */
- if (*ptr == CHAR_LESS_THAN_SIGN)
- terminator = CHAR_GREATER_THAN_SIGN;
- else if (*ptr == CHAR_APOSTROPHE)
- terminator = CHAR_APOSTROPHE;
- else
- {
- errorcode = ERR15;
- goto FAILED;
- }
-
- if (!read_name(&ptr, ptrend, utf, terminator, &next_offset,
- &name, &namelen, &errorcode, cb)) goto FAILED;
-
- meta = META_SCS_NAME;
- }
-
- PCRE2_ASSERT(next_offset > 0);
- if (offset == 0 || (next_offset - offset) >= 0x10000)
- {
- *parsed_pattern++ = META_OFFSET;
- PUTOFFSET(next_offset, parsed_pattern);
- offset = next_offset;
- }
-
- /* The offset is encoded as a relative offset, because for some
- inputs such as ",2" in (*scs:(1,2,3)...), we only have space for
- two uint32_t values, and an opcode and absolute offset may require
- three uint32_t values. */
- *parsed_pattern++ = meta | (uint32_t)(next_offset - offset);
- *parsed_pattern++ = namelen;
- offset = next_offset;
-
- if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS;
-
- if (*ptr == CHAR_RIGHT_PARENTHESIS) break;
-
- if (*ptr != CHAR_COMMA)
- {
- errorcode = ERR24;
- goto FAILED;
- }
-
- ptr++;
- }
- ptr++;
+ parsed_pattern = parse_capture_list(&ptr, ptrend, utf, parsed_pattern,
+ 0, &errorcode, cb);
+ if (parsed_pattern == NULL) goto FAILED;
goto POST_ASSERTION;
case META_LOOKBEHIND:
@@ -4923,7 +5053,6 @@ while (ptr < ptrend)
if (!hyphenok)
{
errorcode = ERR94;
- ptr--; /* Correct the offset */
goto FAILED;
}
optset = &unset;
@@ -4997,7 +5126,6 @@ while (ptr < ptrend)
default:
errorcode = ERR11;
- ptr--; /* Correct the offset */
goto FAILED;
}
}
@@ -5066,7 +5194,7 @@ while (ptr < ptrend)
if (*ptr != CHAR_EQUALS_SIGN)
{
errorcode = ERR41;
- goto FAILED;
+ goto FAILED_FORWARD;
}
if (!read_name(&ptr, ptrend, utf, CHAR_RIGHT_PARENTHESIS, &offset, &name,
&namelen, &errorcode, cb)) goto FAILED;
@@ -5082,23 +5210,30 @@ while (ptr < ptrend)
case CHAR_R:
i = 0; /* (?R) == (?R0) */
ptr++;
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ if (ptr >= ptrend || (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_LEFT_PARENTHESIS))
{
errorcode = ERR58;
goto FAILED;
}
+ terminator = CHAR_NUL;
goto SET_RECURSION;
/* An item starting (?- followed by a digit comes here via the "default"
case because (?- followed by a non-digit is an options setting. */
case CHAR_PLUS:
- if (ptrend - ptr < 2 || !IS_DIGIT(ptr[1]))
+ if (ptr + 1 >= ptrend)
+ {
+ ++ptr;
+ goto UNCLOSED_PARENTHESIS;
+ }
+ if (!IS_DIGIT(ptr[1]))
{
errorcode = ERR29; /* Missing number */
- goto FAILED;
+ ++ptr;
+ goto FAILED_FORWARD;
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
@@ -5108,28 +5243,43 @@ while (ptr < ptrend)
MAX_GROUP_NUMBER, ERR61,
&i, &errorcode)) goto FAILED;
PCRE2_ASSERT(i >= 0); /* NB (?0) is permitted, represented by i=0 */
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
- goto UNCLOSED_PARENTHESIS;
+ terminator = CHAR_NUL;
SET_RECURSION:
*parsed_pattern++ = META_RECURSE | (uint32_t)i;
offset = (PCRE2_SIZE)(ptr - cb->start_pattern);
- ptr++;
- PUTOFFSET(offset, parsed_pattern);
- okquantifier = TRUE;
- break; /* End of recursive call by number handling */
+ /* End of recursive call by number handling */
+ goto READ_RECURSION_ARGUMENTS;
/* ---- Recursion/subroutine calls by name ---- */
case CHAR_AMPERSAND:
RECURSE_BY_NAME:
- if (!read_name(&ptr, ptrend, utf, CHAR_RIGHT_PARENTHESIS, &offset, &name,
+ if (!read_name(&ptr, ptrend, utf, 0, &offset, &name,
&namelen, &errorcode, cb)) goto FAILED;
*parsed_pattern++ = META_RECURSE_BYNAME;
*parsed_pattern++ = namelen;
+ terminator = CHAR_NUL;
+
+ READ_RECURSION_ARGUMENTS:
PUTOFFSET(offset, parsed_pattern);
okquantifier = TRUE;
+
+ /* Arguments are not supported for \g construct. */
+ if (terminator != CHAR_NUL) break;
+
+ if (ptr < ptrend && *ptr == CHAR_LEFT_PARENTHESIS)
+ {
+ parsed_pattern = parse_capture_list(&ptr, ptrend, utf, parsed_pattern,
+ offset, &errorcode, cb);
+ if (parsed_pattern == NULL) goto FAILED;
+ }
+
+ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ goto UNCLOSED_PARENTHESIS;
+
+ ptr++;
break;
/* ---- Callout with numerical or string argument ---- */
@@ -5137,6 +5287,7 @@ while (ptr < ptrend)
case CHAR_C:
if ((xoptions & PCRE2_EXTRA_NEVER_CALLOUT) != 0)
{
+ ptr++;
errorcode = ERR103;
goto FAILED;
}
@@ -5189,7 +5340,7 @@ while (ptr < ptrend)
if (delimiter == 0)
{
errorcode = ERR82;
- goto FAILED;
+ goto FAILED_FORWARD;
}
*parsed_pattern = META_CALLOUT_STRING;
@@ -5333,20 +5484,31 @@ while (ptr < ptrend)
references its argument twice. */
if (*ptr != CHAR_EQUALS_SIGN || (ptr++, !IS_DIGIT(*ptr)))
- goto BAD_VERSION_CONDITION;
+ {
+ errorcode = ERR79;
+ if (!ge) goto FAILED_FORWARD;
+ goto FAILED;
+ }
if (!read_number(&ptr, ptrend, -1, 1000, ERR79, &major, &errorcode))
goto FAILED;
- if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
- if (*ptr == CHAR_DOT)
+ if (ptr < ptrend && *ptr == CHAR_DOT)
{
- if (++ptr >= ptrend || !IS_DIGIT(*ptr)) goto BAD_VERSION_CONDITION;
- minor = (*ptr++ - CHAR_0) * 10;
- if (ptr >= ptrend) goto BAD_VERSION_CONDITION;
- if (IS_DIGIT(*ptr)) minor += *ptr++ - CHAR_0;
- if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
- goto BAD_VERSION_CONDITION;
+ if (++ptr >= ptrend || !IS_DIGIT(*ptr))
+ {
+ errorcode = ERR79;
+ if (ptr < ptrend) goto FAILED_FORWARD;
+ goto FAILED;
+ }
+ if (!read_number(&ptr, ptrend, -1, 1000, ERR79, &minor, &errorcode))
+ goto FAILED;
+ }
+ if (ptr >= ptrend || *ptr != CHAR_RIGHT_PARENTHESIS)
+ {
+ errorcode = ERR79;
+ if (ptr < ptrend) goto FAILED_FORWARD;
+ goto FAILED;
}
*parsed_pattern++ = META_COND_VERSION;
@@ -5380,6 +5542,7 @@ while (ptr < ptrend)
terminator = CHAR_RIGHT_PARENTHESIS;
ptr--; /* Point to char before name */
}
+
if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen,
&errorcode, cb)) goto FAILED;
@@ -5559,21 +5722,37 @@ while (ptr < ptrend)
scanning in case this is a duplicate with the same number. For
non-duplicate names, give an error if the number is duplicated. */
- isdupname = FALSE;
+ is_dupname = FALSE;
+ hash = PRIV(compile_get_hash_from_name)(name, namelen);
ng = cb->named_groups;
for (i = 0; i < cb->names_found; i++, ng++)
{
- if (namelen == ng->length &&
+ if (namelen == ng->length && hash == NAMED_GROUP_GET_HASH(ng) &&
PRIV(strncmp)(name, ng->name, (PCRE2_SIZE)namelen) == 0)
{
+ /* When a bracket is referenced by the same name multiple
+ times, is not considered as a duplicate and ignored. */
if (ng->number == cb->bracount) break;
if ((options & PCRE2_DUPNAMES) == 0)
{
errorcode = ERR43;
goto FAILED;
}
- isdupname = ng->isdup = TRUE; /* Mark as a duplicate */
+
+ ng->hash_dup |= NAMED_GROUP_IS_DUPNAME;
+ is_dupname = TRUE; /* Mark as a duplicate */
cb->dupnames = TRUE; /* Duplicate names exist */
+
+ /* The entry represents a duplicate. */
+ name = ng->name;
+ namelen = 0;
+
+ /* Even duplicated names may refer to the same
+ capture index. These references are also ignored. */
+ for (; i < cb->names_found; i++, ng++)
+ if (ng->name == name && ng->number == cb->bracount)
+ break;
+ break;
}
else if (ng->number == cb->bracount)
{
@@ -5582,7 +5761,8 @@ while (ptr < ptrend)
}
}
- if (i < cb->names_found) break; /* Ignore duplicate with same number */
+ /* Ignore duplicate with same number. */
+ if (i < cb->names_found) break;
/* Increase the list size if necessary */
@@ -5608,11 +5788,13 @@ while (ptr < ptrend)
}
/* Add this name to the list */
+ if (is_dupname)
+ hash |= NAMED_GROUP_IS_DUPNAME;
cb->named_groups[cb->names_found].name = name;
cb->named_groups[cb->names_found].length = (uint16_t)namelen;
cb->named_groups[cb->names_found].number = cb->bracount;
- cb->named_groups[cb->names_found].isdup = (uint16_t)isdupname;
+ cb->named_groups[cb->names_found].hash_dup = hash;
cb->names_found++;
break;
@@ -5678,7 +5860,7 @@ while (ptr < ptrend)
if (nest_depth == 0) /* Unmatched closing parenthesis */
{
errorcode = ERR22;
- goto FAILED_BACK; // TODO https://github.com/PCRE2Project/pcre2/issues/549
+ goto FAILED;
}
nest_depth--;
*parsed_pattern++ = META_KET;
@@ -5723,12 +5905,14 @@ else if ((xoptions & PCRE2_EXTRA_MATCH_WORD) != 0)
/* Terminate the parsed pattern, then return success if all groups are closed.
Otherwise we have unclosed parentheses. */
+/* LCOV_EXCL_START */
if (parsed_pattern >= parsed_pattern_end)
{
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR63; /* Internal error (parsed pattern overflow) */
goto FAILED;
}
+/* LCOV_EXCL_STOP */
*parsed_pattern = META_END;
if (nest_depth == 0) return 0;
@@ -5746,12 +5930,18 @@ return errorcode;
FAILED_BACK:
ptr--;
+#ifdef SUPPORT_UNICODE
+if (utf) BACKCHAR(ptr);
+#endif
goto FAILED;
-/* This failure happens several times. */
+/* Some errors need to indicate the next character. */
-BAD_VERSION_CONDITION:
-errorcode = ERR79;
+FAILED_FORWARD:
+ptr++;
+#ifdef SUPPORT_UNICODE
+if (utf) FORWARDCHARTEST(ptr, ptrend);
+#endif
goto FAILED;
}
@@ -5795,7 +5985,7 @@ for (;;)
case OP_UCP_WORD_BOUNDARY:
case OP_NOT_UCP_WORD_BOUNDARY:
if (!skipassert) return code;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CALLOUT:
case OP_CREF:
@@ -5836,78 +6026,9 @@ for (;;)
}
}
+/* LCOV_EXCL_START */
PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */
-}
-
-
-
-/*************************************************
-* Find details of duplicate group names *
-*************************************************/
-
-/* This is called from compile_branch() when it needs to know the index and
-count of duplicates in the names table when processing named backreferences,
-either directly, or as conditions.
-
-Arguments:
- name points to the name
- length the length of the name
- indexptr where to put the index
- countptr where to put the count of duplicates
- errorcodeptr where to put an error code
- cb the compile block
-
-Returns: TRUE if OK, FALSE if not, error code set
-*/
-
-static BOOL
-find_dupname_details(PCRE2_SPTR name, uint32_t length, int *indexptr,
- int *countptr, int *errorcodeptr, compile_block *cb)
-{
-uint32_t i, groupnumber;
-int count;
-PCRE2_UCHAR *slot = cb->name_table;
-
-/* Find the first entry in the table */
-
-for (i = 0; i < cb->names_found; i++)
- {
- if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) == 0 &&
- slot[IMM2_SIZE+length] == 0) break;
- slot += cb->name_entry_size;
- }
-
-/* This should not occur, because this function is called only when we know we
-have duplicate names. Give an internal error. */
-
-if (i >= cb->names_found)
- {
- PCRE2_DEBUG_UNREACHABLE();
- *errorcodeptr = ERR53;
- cb->erroroffset = name - cb->start_pattern;
- return FALSE;
- }
-
-/* Record the index and then see how many duplicates there are, updating the
-backref map and maximum back reference as we do. */
-
-*indexptr = i;
-count = 0;
-
-for (;;)
- {
- count++;
- groupnumber = GET2(slot,0);
- cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
- if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
- if (++i >= cb->names_found) break;
- slot += cb->name_entry_size;
- if (PRIV(strncmp)(name, slot+IMM2_SIZE, length) != 0 ||
- (slot+IMM2_SIZE)[length] != 0) break;
- }
-
-*countptr = count;
-return TRUE;
+/* LCOV_EXCL_STOP */
}
@@ -5965,7 +6086,7 @@ uint32_t meta, meta_arg;
uint32_t firstcuflags, reqcuflags;
uint32_t zeroreqcuflags, zerofirstcuflags;
uint32_t req_caseopt, reqvary, tempreqvary;
-/* Some opcodes, such as META_SCS_NUMBER or META_SCS_NAME,
+/* Some opcodes, such as META_CAPTURE_NUMBER or META_CAPTURE_NAME,
depends on the previous value of offset. */
PCRE2_SIZE offset = 0;
PCRE2_SIZE length_prevgroup = 0;
@@ -6042,16 +6163,21 @@ for (;; pptr++)
if (lengthptr != NULL)
{
+ /* LCOV_EXCL_START */
+ if (code >= cb->start_workspace + cb->workspace_size)
+ {
+ PCRE2_DEBUG_UNREACHABLE();
+ *errorcodeptr = ERR52; /* Over-ran workspace - internal error */
+ cb->erroroffset = 0;
+ return 0;
+ }
+ /* LCOV_EXCL_STOP */
+
if (code > cb->start_workspace + cb->workspace_size -
WORK_SIZE_SAFETY_MARGIN) /* Check for overrun */
{
- if (code >= cb->start_workspace + cb->workspace_size)
- {
- PCRE2_DEBUG_UNREACHABLE();
- *errorcodeptr = ERR52; /* Over-ran workspace - internal error */
- }
- else
- *errorcodeptr = ERR86;
+ *errorcodeptr = ERR86; /* Pattern too complicated */
+ cb->erroroffset = 0;
return 0;
}
@@ -6072,12 +6198,14 @@ for (;; pptr++)
if (OFLOW_MAX - *lengthptr < (PCRE2_SIZE)(code - orig_code))
{
*errorcodeptr = ERR20; /* Integer overflow */
+ cb->erroroffset = 0;
return 0;
}
*lengthptr += (PCRE2_SIZE)(code - orig_code);
if (*lengthptr > MAX_PATTERN_SIZE)
{
*errorcodeptr = ERR20; /* Pattern is too large */
+ cb->erroroffset = 0;
return 0;
}
code = orig_code;
@@ -6380,7 +6508,7 @@ for (;; pptr++)
case META_PRUNE:
case META_SKIP:
cb->had_pruneorskip = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case META_COMMIT:
case META_FAIL:
*code++ = verbops[(meta - META_MARK) >> 16];
@@ -6405,7 +6533,7 @@ for (;; pptr++)
case META_PRUNE_ARG:
case META_SKIP_ARG:
cb->had_pruneorskip = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case META_MARK:
case META_COMMIT_ARG:
VERB_ARG:
@@ -6450,8 +6578,63 @@ for (;; pptr++)
req_caseopt = ((options & PCRE2_CASELESS) != 0)? REQ_CASELESS : 0;
break;
+ /* ===================================================================*/
+ /* Handle scan substring. Scan substring assertion starts with META_SCS,
+ which recursively calls compile_branch. The first opcode processed by
+ this recursive call is always META_OFFSET. */
+
case META_OFFSET:
- GETPLUSOFFSET(offset, pptr);
+ if (lengthptr != NULL)
+ {
+ pptr = PRIV(compile_parse_scan_substr_args)(pptr, errorcodeptr, cb, lengthptr);
+ if (pptr == NULL)
+ return 0;
+ break;
+ }
+
+ while (TRUE)
+ {
+ int count, index;
+ named_group *ng;
+
+ switch (META_CODE(*pptr))
+ {
+ case META_OFFSET:
+ pptr++;
+ SKIPOFFSET(pptr);
+ continue;
+
+ case META_CAPTURE_NAME:
+ ng = cb->named_groups + pptr[1];
+ pptr += 2;
+ count = 0;
+ index = 0;
+
+ if (!PRIV(compile_find_dupname_details)(ng->name, ng->length, &index,
+ &count, errorcodeptr, cb)) return 0;
+
+ code[0] = OP_DNCREF;
+ PUT2(code, 1, index);
+ PUT2(code, 1 + IMM2_SIZE, count);
+ code += 1 + 2 * IMM2_SIZE;
+ continue;
+
+ case META_CAPTURE_NUMBER:
+ pptr += 2;
+ if (pptr[-1] == 0) continue;
+
+ code[0] = OP_CREF;
+ PUT2(code, 1, pptr[-1]);
+ code += 1 + IMM2_SIZE;
+ continue;
+
+ default:
+ break;
+ }
+
+ break;
+ }
+ --pptr;
break;
case META_SCS:
@@ -6470,19 +6653,17 @@ for (;; pptr++)
case META_COND_RNUMBER: /* (?(Rdigits) */
case META_COND_NAME: /* (?(name) or (?'name') or ?(<name>) */
case META_COND_RNAME: /* (?(R&name) - test for recursion */
- case META_SCS_NAME: /* Name of scan substring */
bravalue = OP_COND;
+
+ if (lengthptr != NULL)
{
- int count, index;
- unsigned int i;
+ uint32_t i;
PCRE2_SPTR name;
- named_group *ng = cb->named_groups;
+ named_group *ng;
+ uint32_t *start_pptr = pptr;
uint32_t length = *(++pptr);
- if (meta == META_SCS_NAME)
- offset += meta_arg;
- else
- GETPLUSOFFSET(offset, pptr);
+ GETPLUSOFFSET(offset, pptr);
name = cb->start_pattern + offset;
/* In the first pass, the names generated in the pre-pass are available,
@@ -6491,11 +6672,9 @@ for (;; pptr++)
this name is duplicated. If it is not duplicated, we can handle it as a
numerical group. */
- for (i = 0; i < cb->names_found; i++, ng++)
- if (length == ng->length &&
- PRIV(strncmp)(name, ng->name, length) == 0) break;
+ ng = PRIV(compile_find_named_group)(name, length, cb);
- if (i >= cb->names_found)
+ if (ng == NULL)
{
/* If the name was not found we have a bad reference, unless we are
dealing with R<digits>, which is treated as a recursion test by
@@ -6528,61 +6707,88 @@ for (;; pptr++)
translated into RREF_ANY (which is 0xffff). */
if (groupnumber == 0) groupnumber = RREF_ANY;
- code[1+LINK_SIZE] = OP_RREF;
- PUT2(code, 2+LINK_SIZE, groupnumber);
+ PCRE2_ASSERT(start_pptr[0] == META_COND_RNUMBER);
+ start_pptr[1] = groupnumber;
skipunits = 1+IMM2_SIZE;
goto GROUP_PROCESS_NOTE_EMPTY;
}
- else if (!ng->isdup)
+
+ /* From here on, we know we have a name (not a number),
+ so treat META_COND_RNUMBER the same as META_COND_NAME. */
+ if (meta == META_COND_RNUMBER) meta = META_COND_NAME;
+
+ if ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) == 0)
{
- /* Otherwise found a duplicated name */
+ /* Found a non-duplicated name. Since it is a global,
+ it is enough to update it in the pre-processing phase. */
if (ng->number > cb->top_backref) cb->top_backref = ng->number;
- if (meta == META_SCS_NAME)
- {
- code[0] = OP_CREF;
- PUT2(code, 1, ng->number);
- code += 1+IMM2_SIZE;
- break;
- }
+ start_pptr[0] = meta;
+ start_pptr[1] = ng->number;
- code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;
- PUT2(code, 2+LINK_SIZE, ng->number);
- skipunits = 1+IMM2_SIZE;
- if (meta != META_SCS_NAME) goto GROUP_PROCESS_NOTE_EMPTY;
- cb->assert_depth += 1;
- goto GROUP_PROCESS;
+ skipunits = 1 + IMM2_SIZE;
+ goto GROUP_PROCESS_NOTE_EMPTY;
}
/* We have a duplicated name. In the compile pass we have to search the
main table in order to get the index and count values. */
- count = 0; /* Values for first pass (avoids compiler warning) */
- index = 0;
- if (lengthptr == NULL && !find_dupname_details(name, length, &index,
- &count, errorcodeptr, cb)) return 0;
+ start_pptr[0] = meta | 1;
+ start_pptr[1] = (uint32_t)(ng - cb->named_groups);
- if (meta == META_SCS_NAME)
+ /* A duplicated name was found. Note that if an R<digits> name is found
+ (META_COND_RNUMBER), it is a reference test, not a recursion test. */
+ skipunits = 1 + 2 * IMM2_SIZE;
+ }
+ else
+ {
+ /* Otherwise lengthptr equals to NULL,
+ which is the second phase of compilation. */
+ int count, index;
+ named_group *ng;
+
+ /* Generate code using the data
+ collected in the pre-processing phase. */
+
+ if (meta == META_COND_RNUMBER)
{
- code[0] = OP_DNCREF;
- PUT2(code, 1, index);
- PUT2(code, 1+IMM2_SIZE, count);
- code += 1+2*IMM2_SIZE;
- break;
+ code[1+LINK_SIZE] = OP_RREF;
+ PUT2(code, 2 + LINK_SIZE, pptr[1]);
+ skipunits = 1 + IMM2_SIZE;
+ pptr += 1 + SIZEOFFSET;
+ goto GROUP_PROCESS_NOTE_EMPTY;
+ }
+
+ if (meta_arg == 0)
+ {
+ code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_RREF : OP_CREF;
+ PUT2(code, 2 + LINK_SIZE, pptr[1]);
+ skipunits = 1 + IMM2_SIZE;
+ pptr += 1 + SIZEOFFSET;
+ goto GROUP_PROCESS_NOTE_EMPTY;
}
+ ng = cb->named_groups + pptr[1];
+ count = 0; /* Values for first pass (avoids compiler warning) */
+ index = 0;
+
+ /* The failed case is an internal error. */
+ if (!PRIV(compile_find_dupname_details)(ng->name, ng->length, &index,
+ &count, errorcodeptr, cb)) return 0;
+
/* A duplicated name was found. Note that if an R<digits> name is found
(META_COND_RNUMBER), it is a reference test, not a recursion test. */
- code[1+LINK_SIZE] = (meta == META_COND_RNAME)? OP_DNRREF : OP_DNCREF;
+ code[1 + LINK_SIZE] = (meta == META_COND_RNAME)? OP_DNRREF : OP_DNCREF;
/* Insert appropriate data values. */
- skipunits = 1+2*IMM2_SIZE;
- PUT2(code, 2+LINK_SIZE, index);
- PUT2(code, 2+LINK_SIZE+IMM2_SIZE, count);
+ PUT2(code, 2 + LINK_SIZE, index);
+ PUT2(code, 2 + LINK_SIZE + IMM2_SIZE, count);
+ skipunits = 1 + 2 * IMM2_SIZE;
+ pptr += 1 + SIZEOFFSET;
}
- PCRE2_ASSERT(meta != META_SCS_NAME);
+ PCRE2_ASSERT(meta != META_CAPTURE_NAME);
goto GROUP_PROCESS_NOTE_EMPTY;
/* The DEFINE condition is always false. Its internal groups may never
@@ -6599,12 +6805,8 @@ for (;; pptr++)
/* Conditional test of a group's being set. */
case META_COND_NUMBER:
- case META_SCS_NUMBER:
bravalue = OP_COND;
- if (meta == META_SCS_NUMBER)
- offset += meta_arg;
- else
- GETPLUSOFFSET(offset, pptr);
+ GETPLUSOFFSET(offset, pptr);
groupnumber = *(++pptr);
if (groupnumber > cb->bracount)
@@ -6615,14 +6817,6 @@ for (;; pptr++)
}
if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
- if (meta == META_SCS_NUMBER)
- {
- code[0] = OP_CREF;
- PUT2(code, 1, groupnumber);
- code += 1+IMM2_SIZE;
- break;
- }
-
/* Point at initial ( for too many branches error */
offset -= 2;
code[1+LINK_SIZE] = OP_CREF;
@@ -6930,8 +7124,7 @@ for (;; pptr++)
{
int count, index;
PCRE2_SPTR name;
- BOOL is_dupname = FALSE;
- named_group *ng = cb->named_groups;
+ named_group *ng;
uint32_t length = *(++pptr);
GETPLUSOFFSET(offset, pptr);
@@ -6942,47 +7135,39 @@ for (;; pptr++)
generated in the pre-pass in order to get a number and whether or not
this name is duplicated. */
- groupnumber = 0;
- for (unsigned int i = 0; i < cb->names_found; i++, ng++)
+ ng = PRIV(compile_find_named_group)(name, length, cb);
+
+ if (ng == NULL)
{
- if (length == ng->length &&
- PRIV(strncmp)(name, ng->name, length) == 0)
- {
- is_dupname = ng->isdup;
- groupnumber = ng->number;
+ /* If the name was not found we have a bad reference. */
+ *errorcodeptr = ERR15;
+ cb->erroroffset = offset;
+ return 0;
+ }
- /* For a recursion, that's all that is needed. We can now go to
- the code that handles numerical recursion, applying it to the first
- group with the given name. */
+ groupnumber = ng->number;
- if (meta == META_RECURSE_BYNAME)
- {
- meta_arg = groupnumber;
- goto HANDLE_NUMERICAL_RECURSION;
- }
-
- /* For a back reference, update the back reference map and the
- maximum back reference. */
+ /* For a recursion, that's all that is needed. We can now go to
+ the code that handles numerical recursion, applying it to the first
+ group with the given name. */
- cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
- if (groupnumber > cb->top_backref)
- cb->top_backref = groupnumber;
- }
+ if (meta == META_RECURSE_BYNAME)
+ {
+ meta_arg = groupnumber;
+ goto HANDLE_NUMERICAL_RECURSION;
}
- /* If the name was not found we have a bad reference. */
+ /* For a back reference, update the back reference map and the
+ maximum back reference. */
- if (groupnumber == 0)
- {
- *errorcodeptr = ERR15;
- cb->erroroffset = offset;
- return 0;
- }
+ cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
+ if (groupnumber > cb->top_backref)
+ cb->top_backref = groupnumber;
/* If a back reference name is not duplicated, we can handle it as
a numerical reference. */
- if (!is_dupname)
+ if ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) == 0)
{
meta_arg = groupnumber;
goto HANDLE_SINGLE_REFERENCE;
@@ -6994,8 +7179,8 @@ for (;; pptr++)
count = 0; /* Values for first pass (avoids compiler warning) */
index = 0;
- if (lengthptr == NULL && !find_dupname_details(name, length, &index,
- &count, errorcodeptr, cb)) return 0;
+ if (lengthptr == NULL && !PRIV(compile_find_dupname_details)(name, length,
+ &index, &count, errorcodeptr, cb)) return 0;
if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
*code++ = ((options & PCRE2_CASELESS) != 0)? OP_DNREFI : OP_DNREF;
@@ -7279,6 +7464,7 @@ for (;; pptr++)
if (repeat_min > 0 && (repeat_min != 1 || repeat_max != REPEAT_UNLIMITED))
{
int replicate = repeat_min;
+
if (repeat_min == repeat_max) replicate--;
/* In the pre-compile phase, we don't actually do the replication. We
@@ -7288,7 +7474,7 @@ for (;; pptr++)
if (lengthptr != NULL)
{
PCRE2_SIZE delta;
- if (PRIV(ckd_smul)(&delta, replicate, 1 + LINK_SIZE) ||
+ if (PRIV(ckd_smul)(&delta, replicate, (int)length_prevgroup) ||
OFLOW_MAX - *lengthptr < delta)
{
*errorcodeptr = ERR20;
@@ -7296,12 +7482,11 @@ for (;; pptr++)
}
*lengthptr += delta;
}
-
else for (int i = 0; i < replicate; i++)
{
- memcpy(code, previous, CU2BYTES(1 + LINK_SIZE));
+ memcpy(code, previous, CU2BYTES(length_prevgroup));
previous = code;
- code += 1 + LINK_SIZE;
+ code += length_prevgroup;
}
/* If the number of repeats is fixed, we are done. Otherwise, adjust
@@ -7313,18 +7498,21 @@ for (;; pptr++)
}
/* Wrap the recursion call in OP_BRA brackets. */
+ {
+ PCRE2_SIZE length = (lengthptr != NULL) ? 1 + LINK_SIZE : length_prevgroup;
- (void)memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(1 + LINK_SIZE));
- op_previous = *previous = OP_BRA;
- PUT(previous, 1, 2 + 2*LINK_SIZE);
- previous[2 + 2*LINK_SIZE] = OP_KET;
- PUT(previous, 3 + 2*LINK_SIZE, 2 + 2*LINK_SIZE);
+ (void)memmove(previous + 1 + LINK_SIZE, previous, CU2BYTES(length));
+ op_previous = *previous = OP_BRA;
+ PUT(previous, 1, 1 + LINK_SIZE + length);
+ previous[1 + LINK_SIZE + length] = OP_KET;
+ PUT(previous, 2 + LINK_SIZE + length, 1 + LINK_SIZE + length);
+ }
code += 2 + 2 * LINK_SIZE;
- length_prevgroup = 3 + 3*LINK_SIZE;
+ length_prevgroup += 2 + 2 * LINK_SIZE;
group_return = -1; /* Set "may match empty string" */
/* Now treat as a repeated OP_BRA. */
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* If previous was a bracket group, we may have to replicate it in
certain cases. Note that at this point we can encounter only the "basic"
@@ -7664,13 +7852,16 @@ for (;; pptr++)
here because it just makes it horribly messy. */
default:
+
+ /* LCOV_EXCL_START */
if (op_previous >= OP_EODN || op_previous <= OP_WORD_BOUNDARY)
{
PCRE2_DEBUG_UNREACHABLE();
*errorcodeptr = ERR10; /* Not a character type - internal error */
return 0;
}
- else
+ /* LCOV_EXCL_STOP */
+
{
int prop_type, prop_value;
PCRE2_UCHAR *oldcode;
@@ -7993,6 +8184,52 @@ for (;; pptr++)
*code = OP_RECURSE;
PUT(code, 1, meta_arg);
code += 1 + LINK_SIZE;
+ /* Repeat processing requires this information to
+ determine the real length in pre-compile phase. */
+ length_prevgroup = 1 + LINK_SIZE;
+
+ if (META_CODE(pptr[1]) == META_OFFSET ||
+ META_CODE(pptr[1]) == META_CAPTURE_NAME ||
+ META_CODE(pptr[1]) == META_CAPTURE_NUMBER)
+ {
+ recurse_arguments *args;
+
+ if (lengthptr != NULL)
+ {
+ if (!PRIV(compile_parse_recurse_args)(pptr, offset, errorcodeptr, cb))
+ return 0;
+
+ args = (recurse_arguments*)cb->last_data;
+ length_prevgroup += (args->size * (1 + IMM2_SIZE));
+ *lengthptr += (args->size * (1 + IMM2_SIZE));
+ pptr += args->skip_size;
+ }
+ else
+ {
+ uint16_t *current, *end;
+
+ args = (recurse_arguments*)cb->first_data;
+ PCRE2_ASSERT(args != NULL && args->header.type == CDATA_RECURSE_ARGS);
+
+ current = (uint16_t*)(args + 1);
+ end = current + args->size;
+ PCRE2_ASSERT(end > current);
+
+ do
+ {
+ code[0] = OP_CREF;
+ PUT2(code, 1, *current);
+ code += 1 + IMM2_SIZE;
+ }
+ while (++current < end);
+
+ length_prevgroup += (args->size * (1 + IMM2_SIZE));
+ pptr += args->skip_size;
+ cb->first_data = args->header.next;
+ cb->cx->memctl.free(args, cb->cx->memctl.memory_data);
+ }
+ }
+
groupsetfirstcu = FALSE;
cb->had_recurse = TRUE;
if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE;
@@ -8117,6 +8354,7 @@ for (;; pptr++)
cb->external_flags |= PCRE2_HASBKC; /* Record */
#if PCRE2_CODE_UNIT_WIDTH == 32
meta_arg = OP_ALLANY;
+ (void)utf; /* Avoid compiler warning. */
#else
if (!utf) meta_arg = OP_ALLANY;
#endif
@@ -8127,11 +8365,15 @@ for (;; pptr++)
if ((options & PCRE2_UCP) != 0 && (xoptions & PCRE2_EXTRA_ASCII_BSW) == 0)
meta_arg = (meta_arg == ESC_B)? OP_NOT_UCP_WORD_BOUNDARY :
OP_UCP_WORD_BOUNDARY;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case ESC_A:
if (cb->max_lookbehind == 0) cb->max_lookbehind = 1;
break;
+
+ case ESC_K:
+ cb->external_flags |= PCRE2_HASBSK; /* Record */
+ break;
}
*code++ = meta_arg;
@@ -8143,12 +8385,14 @@ for (;; pptr++)
META_END is a literal. Otherwise we have a problem. */
default:
+ /* LCOV_EXCL_START */
if (meta >= META_END)
{
PCRE2_DEBUG_UNREACHABLE();
*errorcodeptr = ERR89; /* Internal error - unrecognized. */
return 0;
}
+ /* LCOV_EXCL_STOP */
/* Handle a literal character. We come here by goto in the case of a
32-bit, non-UTF character whose value is greater than META_END. */
@@ -8280,8 +8524,10 @@ for (;; pptr++)
} /* End of big switch */
} /* End of big loop */
+/* LCOV_EXCL_START */
PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */
return 0; /* Avoid compiler warnings */
+/* LCOV_EXCL_STOP */
}
@@ -8346,6 +8592,7 @@ if (cb->cx->stack_guard != NULL &&
cb->cx->stack_guard(cb->parens_depth, cb->cx->stack_guard_data))
{
*errorcodeptr= ERR33;
+ cb->erroroffset = 0;
return 0;
}
@@ -8587,8 +8834,10 @@ for (;;)
pptr++;
}
+/* LCOV_EXCL_START */
PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */
return 0; /* Avoid compiler warnings */
+/* LCOV_EXCL_STOP */
}
@@ -9060,7 +9309,7 @@ do {
case OP_EXACT:
scode += IMM2_SIZE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CHAR:
case OP_PLUS:
@@ -9073,7 +9322,7 @@ do {
case OP_EXACTI:
scode += IMM2_SIZE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CHARI:
case OP_PLUSI:
@@ -9109,67 +9358,6 @@ return c;
/*************************************************
-* Add an entry to the name/number table *
-*************************************************/
-
-/* This function is called between compiling passes to add an entry to the
-name/number table, maintaining alphabetical order. Checking for permitted
-and forbidden duplicates has already been done.
-
-Arguments:
- cb the compile data block
- name the name to add
- length the length of the name
- groupno the group number
- tablecount the count of names in the table so far
-
-Returns: nothing
-*/
-
-static void
-add_name_to_table(compile_block *cb, PCRE2_SPTR name, int length,
- unsigned int groupno, uint32_t tablecount)
-{
-uint32_t i;
-PCRE2_UCHAR *slot = cb->name_table;
-
-for (i = 0; i < tablecount; i++)
- {
- int crc = memcmp(name, slot+IMM2_SIZE, CU2BYTES(length));
- if (crc == 0 && slot[IMM2_SIZE+length] != 0)
- crc = -1; /* Current name is a substring */
-
- /* Make space in the table and break the loop for an earlier name. For a
- duplicate or later name, carry on. We do this for duplicates so that in the
- simple case (when ?(| is not used) they are in order of their numbers. In all
- cases they are in the order in which they appear in the pattern. */
-
- if (crc < 0)
- {
- (void)memmove(slot + cb->name_entry_size, slot,
- CU2BYTES((tablecount - i) * cb->name_entry_size));
- break;
- }
-
- /* Continue the loop for a later or duplicate name */
-
- slot += cb->name_entry_size;
- }
-
-PUT2(slot, 0, groupno);
-memcpy(slot + IMM2_SIZE, name, CU2BYTES(length));
-
-/* Add a terminating zero and fill the rest of the slot with zeroes so that
-the memory is all initialized. Otherwise valgrind moans about uninitialized
-memory when saving serialized compiled patterns. */
-
-memset(slot + IMM2_SIZE + length, 0,
- CU2BYTES(cb->name_entry_size - length - IMM2_SIZE));
-}
-
-
-
-/*************************************************
* Skip in parsed pattern *
*************************************************/
@@ -9210,13 +9398,14 @@ for (;; pptr++)
if (meta < META_END) continue; /* Literal */
break;
- case META_END:
-
/* The parsed regex is malformed; we have reached the end and did
not find the end of the construct which we are skipping over. */
+ /* LCOV_EXCL_START */
+ case META_END:
PCRE2_DEBUG_UNREACHABLE();
return NULL;
+ /* LCOV_EXCL_STOP */
/* The data for these items is variable in length. */
@@ -9281,7 +9470,9 @@ for (;; pptr++)
pptr += meta_extra_lengths[meta];
}
+/* LCOV_EXCL_START */
PCRE2_UNREACHABLE(); /* Control never reaches here */
+/* LCOV_EXCL_STOP */
}
@@ -9566,36 +9757,30 @@ for (;; pptr++)
case META_BACKREF_BYNAME:
if ((cb->external_options & PCRE2_MATCH_UNSET_BACKREF) != 0)
goto ISNOTFIXED;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case META_RECURSE_BYNAME:
{
- int i;
PCRE2_SPTR name;
BOOL is_dupname = FALSE;
- named_group *ng = cb->named_groups;
+ named_group *ng;
uint32_t meta_code = META_CODE(*pptr);
uint32_t length = *(++pptr);
GETPLUSOFFSET(offset, pptr);
name = cb->start_pattern + offset;
- for (i = 0; i < cb->names_found; i++, ng++)
- {
- if (length == ng->length && PRIV(strncmp)(name, ng->name, length) == 0)
- {
- group = ng->number;
- is_dupname = ng->isdup;
- break;
- }
- }
+ ng = PRIV(compile_find_named_group)(name, length, cb);
- if (group == 0)
+ if (ng == NULL)
{
*errcodeptr = ERR15; /* Non-existent subpattern */
cb->erroroffset = offset;
return -1;
}
+ group = ng->number;
+ is_dupname = (ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0;
+
/* A numerical back reference can be fixed length if duplicate capturing
groups are not being used. A non-duplicate named back reference can also
be handled. */
@@ -9621,7 +9806,7 @@ for (;; pptr++)
goto RECURSE_OR_BACKREF_LENGTH;
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* For groups >= 10 - picking up group twice does no harm. */
/* A true recursion implies not fixed length, but a subroutine call may
@@ -9701,7 +9886,7 @@ for (;; pptr++)
case META_CAPTURE:
group = META_DATA(*pptr);
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case META_ATOMIC:
case META_NOCAPTURE:
@@ -9748,7 +9933,7 @@ for (;; pptr++)
else itemlength = (max - 1) * lastitemlength;
break;
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* Any other item means this branch does not have a fixed length. */
@@ -9783,10 +9968,12 @@ EXIT:
*minptr = branchminlength;
return branchlength;
+/* LCOV_EXCL_START */
PARSED_SKIP_FAILED:
PCRE2_DEBUG_UNREACHABLE();
*errcodeptr = ERR90; /* Unhandled META code - internal error */
return -1;
+/* LCOV_EXCL_STOP */
}
@@ -9922,15 +10109,16 @@ for (; *pptr != META_END; pptr++)
switch (META_CODE(*pptr))
{
- default:
-
/* The following erroroffset is a bogus but safe value. This branch should
be avoided by providing a proper implementation for all supported cases
below. */
+ /* LCOV_EXCL_START */
+ default:
PCRE2_DEBUG_UNREACHABLE();
cb->erroroffset = 0;
return ERR70; /* Unrecognized meta code */
+ /* LCOV_EXCL_STOP */
case META_ESCAPE:
if (*pptr - META_ESCAPE == ESC_P || *pptr - META_ESCAPE == ESC_p)
@@ -10021,8 +10209,8 @@ for (; *pptr != META_END; pptr++)
case META_BIGVALUE:
case META_POSIX:
case META_POSIX_NEG:
- case META_SCS_NAME:
- case META_SCS_NUMBER:
+ case META_CAPTURE_NAME:
+ case META_CAPTURE_NUMBER:
pptr += 1;
break;
@@ -10093,8 +10281,9 @@ pcre2_real_code *re = NULL; /* What we will return */
compile_block cb; /* "Static" compile-time data */
const uint8_t *tables; /* Char tables base pointer */
+PCRE2_UCHAR null_str[1] = { 0xcd }; /* Dummy for handling null inputs */
PCRE2_UCHAR *code; /* Current pointer in compiled code */
-PCRE2_UCHAR * codestart; /* Start of compiled code */
+PCRE2_UCHAR *codestart; /* Start of compiled code */
PCRE2_SPTR ptr; /* Current pointer in pattern */
uint32_t *pptr; /* Current pointer in parsed pattern */
@@ -10141,7 +10330,16 @@ PCRE2_UCHAR *cworkspace = (PCRE2_UCHAR *)c16workspace;
/* There must be error code and offset pointers. */
-if (errorptr == NULL || erroroffset == NULL) return NULL;
+if (errorptr == NULL)
+ {
+ if (erroroffset != NULL) *erroroffset = 0;
+ return NULL;
+ }
+if (erroroffset == NULL)
+ {
+ if (errorptr != NULL) *errorptr = ERR120;
+ return NULL;
+ }
*errorptr = ERR0;
*erroroffset = 0;
@@ -10149,7 +10347,9 @@ if (errorptr == NULL || erroroffset == NULL) return NULL;
if (pattern == NULL)
{
- if (patlen == 0) pattern = (PCRE2_SPTR)""; else
+ if (patlen == 0)
+ pattern = null_str;
+ else
{
*errorptr = ERR16;
return NULL;
@@ -10245,9 +10445,9 @@ cb.start_code = cworkspace;
cb.start_pattern = pattern;
cb.start_workspace = cworkspace;
cb.workspace_size = COMPILE_WORK_SIZE;
+cb.first_data = NULL;
+cb.last_data = NULL;
#ifdef SUPPORT_WIDE_CHARS
-cb.cranges = NULL;
-cb.next_cranges = NULL;
cb.char_lists_size = 0;
#endif
@@ -10341,6 +10541,7 @@ if ((options & PCRE2_LITERAL) == 0)
{
errorcode = ERR60;
ptr += pp;
+ utf = FALSE; /* Used by HAD_EARLY_ERROR */
goto HAD_EARLY_ERROR;
}
if (p->type == PSO_LIMH) limit_heap = c;
@@ -10373,11 +10574,13 @@ if ((options & PCRE2_LITERAL) == 0)
break;
+ /* LCOV_EXCL_START */
default:
/* All values in the enum need an explicit entry for this switch
but until a better way to prevent coding mistakes is invented keep
a catch all that triggers a debug build assert as a failsafe */
PCRE2_DEBUG_UNREACHABLE();
+ /* LCOV_EXCL_STOP */
}
break; /* Out of the table scan loop */
}
@@ -10500,10 +10703,12 @@ switch(newline)
cb.nltype = NLTYPE_ANYCRLF;
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR56;
goto HAD_EARLY_ERROR;
+ /* LCOV_EXCL_STOP */
}
/* Pre-scan the pattern to do two things: (1) Discover the named groups and
@@ -10632,6 +10837,7 @@ if (length > MAX_PATTERN_SIZE)
#endif
{
errorcode = ERR20;
+ cb.erroroffset = 0;
goto HAD_CB_ERROR;
}
@@ -10660,6 +10866,7 @@ re_blocksize += CU2BYTES(length);
if (re_blocksize > ccontext->max_pattern_compiled_length)
{
errorcode = ERR101;
+ cb.erroroffset = 0;
goto HAD_CB_ERROR;
}
@@ -10669,6 +10876,7 @@ re = (pcre2_real_code *)
if (re == NULL)
{
errorcode = ERR21;
+ cb.erroroffset = 0;
goto HAD_CB_ERROR;
}
@@ -10734,8 +10942,14 @@ created in the pre-pass. */
if (cb.names_found > 0)
{
named_group *ng = cb.named_groups;
+ uint32_t tablecount = 0;
+
+ /* Length 0 represents duplicates, and they have already been handled. */
for (i = 0; i < cb.names_found; i++, ng++)
- add_name_to_table(&cb, ng->name, ng->length, ng->number, i);
+ if (ng->length > 0)
+ tablecount = PRIV(compile_add_name_to_table)(&cb, ng, tablecount);
+
+ PCRE2_ASSERT(tablecount == cb.names_found);
}
/* Set up a starting, non-extracting bracket, then compile the expression. On
@@ -10767,18 +10981,20 @@ memory as unaddressable, so that any out-of-bound reads can be detected. */
*code++ = OP_END;
usedlength = code - codestart;
+/* LCOV_EXCL_START */
if (usedlength > length)
{
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR23; /* Overflow of code block - internal error */
+ cb.erroroffset = 0;
+ goto HAD_CB_ERROR;
}
-else
- {
- re->blocksize -= CU2BYTES(length - usedlength);
+/* LCOV_EXCL_STOP */
+
+re->blocksize -= CU2BYTES(length - usedlength);
#ifdef SUPPORT_VALGRIND
- VALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength));
+VALGRIND_MAKE_MEM_NOACCESS(code, CU2BYTES(length - usedlength));
#endif
- }
/* Scan the pattern for recursion/subroutine calls and convert the group
numbers into offsets. Maintain a small cache so that repeated groups containing
@@ -10823,12 +11039,15 @@ if (errorcode == 0 && cb.had_recurse)
if (rgroup == NULL)
{
rgroup = PRIV(find_bracket)(search_from, utf, groupnumber);
+ /* LCOV_EXCL_START */
if (rgroup == NULL)
{
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR53;
break;
}
+ /* LCOV_EXCL_STOP */
+
if (--start < 0) start = RSCAN_CACHE_SIZE - 1;
rc[start].groupnumber = groupnumber;
rc[start].group = rgroup;
@@ -10858,11 +11077,15 @@ function call. */
if (errorcode == 0 && (optim_flags & PCRE2_OPTIM_AUTO_POSSESS) != 0)
{
PCRE2_UCHAR *temp = (PCRE2_UCHAR *)codestart;
- if (PRIV(auto_possessify)(temp, &cb) != 0)
+ int possessify_rc = PRIV(auto_possessify)(temp, &cb);
+ /* LCOV_EXCL_START */
+ if (possessify_rc != 0)
{
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR80;
+ cb.erroroffset = 0;
}
+ /* LCOV_EXCL_STOP */
}
/* Failed to compile, or error while post-processing. */
@@ -10892,6 +11115,7 @@ unit. */
if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)
{
int minminlength = 0; /* For minimal minlength from first/required CU */
+ int study_rc;
/* If we do not have a first code unit, see if there is one that is asserted
(these are not saved during the compile because they can cause conflicts with
@@ -11015,12 +11239,16 @@ if ((optim_flags & PCRE2_OPTIM_START_OPTIMIZE) != 0)
/* Study the compiled pattern to set up information such as a bitmap of
starting code units and a minimum matching length. */
- if (PRIV(study)(re) != 0)
+ study_rc = PRIV(study)(re);
+ /* LCOV_EXCL_START */
+ if (study_rc != 0)
{
PCRE2_DEBUG_UNREACHABLE();
errorcode = ERR31;
+ cb.erroroffset = 0;
goto HAD_CB_ERROR;
}
+ /* LCOV_EXCL_STOP */
/* If study() set a bitmap of starting code units, it implies a minimum
length of at least one. */
@@ -11041,7 +11269,8 @@ groups if a larger one had to be obtained, and likewise the group information
vector. */
#ifdef SUPPORT_UNICODE
-PCRE2_ASSERT(cb.cranges == NULL);
+/* All items must be freed. */
+PCRE2_ASSERT(cb.first_data == NULL);
#endif
EXIT:
@@ -11067,8 +11296,22 @@ HAD_CB_ERROR:
ptr = pattern + cb.erroroffset;
HAD_EARLY_ERROR:
-PCRE2_ASSERT(ptr >= pattern); /* Ensure we don't return invalid erroroffset */
+/* Ensure we don't return out-of-range erroroffset. */
+PCRE2_ASSERT(ptr >= pattern);
PCRE2_ASSERT(ptr <= (pattern + patlen));
+/* Ensure that the erroroffset never slices a UTF-encoded character in half.
+If the input is invalid, then we return an offset just before the first invalid
+character, so the text to the left of the offset must always be valid. */
+#if defined PCRE2_DEBUG && defined SUPPORT_UNICODE
+if (ptr > pattern && utf)
+ {
+ PCRE2_SPTR prev = ptr - 1;
+ PCRE2_SIZE dummyoffset;
+ BACKCHAR(prev);
+ PCRE2_ASSERT(prev >= pattern);
+ PCRE2_ASSERT(PRIV(valid_utf)(prev, ptr - prev, &dummyoffset) == 0);
+ }
+#endif
*erroroffset = ptr - pattern;
HAD_ERROR:
@@ -11076,19 +11319,18 @@ HAD_ERROR:
pcre2_code_free(re);
re = NULL;
-#ifdef SUPPORT_WIDE_CHARS
-if (cb.cranges != NULL)
+if (cb.first_data != NULL)
{
- class_ranges* cranges = cb.cranges;
+ compile_data* current_data = cb.first_data;
do
{
- class_ranges* next_cranges = cranges->next;
- cb.cx->memctl.free(cranges, cb.cx->memctl.memory_data);
- cranges = next_cranges;
+ compile_data* next_data = current_data->next;
+ cb.cx->memctl.free(current_data, cb.cx->memctl.memory_data);
+ current_data = next_data;
}
- while (cranges != NULL);
+ while (current_data != NULL);
}
-#endif
+
goto EXIT;
}
diff --git a/src/3rdparty/pcre2/src/pcre2_compile.h b/src/3rdparty/pcre2/src/pcre2_compile.h
index c8bf610bed5..331ca3ad396 100644
--- a/src/3rdparty/pcre2/src/pcre2_compile.h
+++ b/src/3rdparty/pcre2/src/pcre2_compile.h
@@ -51,18 +51,18 @@ pcre2.h.in must be updated - their values are exactly 100 greater than these
values. */
enum { ERR0 = COMPILE_ERROR_BASE,
- ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10,
- ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,
- ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30,
- ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40,
- ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50,
- ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60,
- ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70,
- ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80,
- ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90,
- ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100,
- ERR101,ERR102,ERR103,ERR104,ERR105,ERR106,ERR107,ERR108,ERR109,ERR110,
- ERR111,ERR112,ERR113,ERR114,ERR115,ERR116 };
+ ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10,
+ ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20,
+ ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29, ERR30,
+ ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40,
+ ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49, ERR50,
+ ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59, ERR60,
+ ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70,
+ ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80,
+ ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90,
+ ERR91, ERR92, ERR93, ERR94, ERR95, ERR96, ERR97, ERR98, ERR99, ERR100,
+ ERR101, ERR102, ERR103, ERR104, ERR105, ERR106, ERR107, ERR108, ERR109, ERR110,
+ ERR111, ERR112, ERR113, ERR114, ERR115, ERR116, ERR117, ERR118, ERR119, ERR120 };
/* Code values for parsed patterns, which are stored in a vector of 32-bit
unsigned ints. Values less than META_END are literal data values. The coding
@@ -96,11 +96,11 @@ code (meta_extra_lengths) must be updated to remain in step. */
#define META_COND_RNAME 0x80130000u /* (?(R&name)... */
#define META_COND_RNUMBER 0x80140000u /* (?(Rdigits)... */
#define META_COND_VERSION 0x80150000u /* (?(VERSION<op>x.y)... */
-#define META_OFFSET 0x80160000u /* Setting offset for various
- META codes (e.g. META_SCS_NAME) */
+#define META_OFFSET 0x80160000u /* Setting offset for various META
+ codes (e.g. META_CAPTURE_NAME) */
#define META_SCS 0x80170000u /* (*scan_substring:... */
-#define META_SCS_NAME 0x80180000u /* Next <name> of scan_substring */
-#define META_SCS_NUMBER 0x80190000u /* Next digits of scan_substring */
+#define META_CAPTURE_NAME 0x80180000u /* Next <name> in capture lists */
+#define META_CAPTURE_NUMBER 0x80190000u /* Next digits in capture lists */
#define META_DOLLAR 0x801a0000u /* $ metacharacter */
#define META_DOT 0x801b0000u /* . metacharacter */
#define META_ESCAPE 0x801c0000u /* \d and friends */
@@ -186,6 +186,36 @@ therefore no need for it to have a length entry, so use a high value. */
#define META_DATA(x) (x & 0x0000ffffu)
#define META_DIFF(x,y) ((x-y)>>16)
+/* Macros to store and retrieve a PCRE2_SIZE value in the parsed pattern, which
+consists of uint32_t elements. Assume that if uint32_t can't hold it, two of
+them will be able to (i.e. assume a 64-bit world). */
+
+#if PCRE2_SIZE_MAX <= UINT32_MAX
+#define PUTOFFSET(s,p) *p++ = s
+#define GETOFFSET(s,p) s = *p++
+#define GETPLUSOFFSET(s,p) s = *(++p)
+#define READPLUSOFFSET(s,p) s = p[1]
+#define SKIPOFFSET(p) p++
+#define SIZEOFFSET 1
+#else
+#define PUTOFFSET(s,p) \
+ { *p++ = (uint32_t)(s >> 32); *p++ = (uint32_t)(s & 0xffffffff); }
+#define GETOFFSET(s,p) \
+ { s = ((PCRE2_SIZE)p[0] << 32) | (PCRE2_SIZE)p[1]; p += 2; }
+#define GETPLUSOFFSET(s,p) \
+ { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; p += 2; }
+#define READPLUSOFFSET(s,p) \
+ { s = ((PCRE2_SIZE)p[1] << 32) | (PCRE2_SIZE)p[2]; }
+#define SKIPOFFSET(p) p += 2
+#define SIZEOFFSET 2
+#endif
+
+#ifdef PCRE2_DEBUG
+/* Compile data types. */
+#define CDATA_RECURSE_ARGS 0 /* Argument list for recurse */
+#define CDATA_CRANGE 1 /* Character range list */
+#endif
+
/* Extended class management flags. */
#define CLASS_IS_ECLASS 0x1
@@ -236,10 +266,16 @@ typedef struct {
/* Macros for the definitions below, to prevent name collisions. */
-#define _pcre2_posix_class_maps PCRE2_SUFFIX(_pcre2_posix_class_maps)
-#define _pcre2_update_classbits PCRE2_SUFFIX(_pcre2_update_classbits_)
-#define _pcre2_compile_class_nested PCRE2_SUFFIX(_pcre2_compile_class_nested_)
-#define _pcre2_compile_class_not_nested PCRE2_SUFFIX(_pcre2_compile_class_not_nested_)
+#define _pcre2_posix_class_maps PCRE2_SUFFIX(_pcre2_posix_class_maps)
+#define _pcre2_update_classbits PCRE2_SUFFIX(_pcre2_update_classbits_)
+#define _pcre2_compile_class_nested PCRE2_SUFFIX(_pcre2_compile_class_nested_)
+#define _pcre2_compile_class_not_nested PCRE2_SUFFIX(_pcre2_compile_class_not_nested_)
+#define _pcre2_compile_get_hash_from_name PCRE2_SUFFIX(_pcre2_compile_get_hash_from_name)
+#define _pcre2_compile_find_named_group PCRE2_SUFFIX(_pcre2_compile_find_named_group)
+#define _pcre2_compile_find_dupname_details PCRE2_SUFFIX(_pcre2_compile_find_dupname_details)
+#define _pcre2_compile_add_name_to_table PCRE2_SUFFIX(_pcre2_compile_add_name_to_table)
+#define _pcre2_compile_parse_scan_substr_args PCRE2_SUFFIX(_pcre2_compile_parse_scan_substr_args)
+#define _pcre2_compile_parse_recurse_args PCRE2_SUFFIX(_pcre2_compile_parse_recurse_args)
/* Indices of the POSIX classes in posix_names, posix_name_lengths,
@@ -253,6 +289,14 @@ posix_class_maps, and posix_substitutes. They must be kept in sync. */
extern const int PRIV(posix_class_maps)[];
+/* Defines for hash_dup member in named_group structure. */
+
+#define NAMED_GROUP_HASH_MASK ((uint16_t)0x7fff)
+#define NAMED_GROUP_IS_DUPNAME ((uint16_t)0x8000)
+
+#define NAMED_GROUP_GET_HASH(ng) ((ng)->hash_dup & NAMED_GROUP_HASH_MASK)
+
+/* Exported functions from pcre2_compile_class.c file: */
/* Set bits in classbits according to the property type */
@@ -275,6 +319,38 @@ BOOL PRIV(compile_class_nested)(uint32_t options, uint32_t xoptions,
uint32_t **pptr, PCRE2_UCHAR **pcode, int *errorcodeptr,
compile_block *cb, PCRE2_SIZE *lengthptr);
+/* Exported functions from pcre2_compile_cgroup.c file: */
+
+/* Compute hash from a capture name. */
+
+uint16_t PRIV(compile_get_hash_from_name)(PCRE2_SPTR name, uint32_t length);
+
+/* Get the descriptor of a known named capture. */
+
+named_group *PRIV(compile_find_named_group)(PCRE2_SPTR name,
+ uint32_t length, compile_block *cb);
+
+/* Add entires to name table in alphabetical order. */
+
+uint32_t PRIV(compile_add_name_to_table)(compile_block *cb,
+ named_group *ng, uint32_t tablecount);
+
+/* Searches the properties of duplicated names, and returns them
+in indexptr and countptr. */
+
+BOOL PRIV(compile_find_dupname_details)(PCRE2_SPTR name, uint32_t length,
+ int *indexptr, int *countptr, int *errorcodeptr, compile_block *cb);
+
+/* Parse the arguments of recurse operations. */
+
+uint32_t * PRIV(compile_parse_scan_substr_args)(uint32_t *pptr,
+ int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr);
+
+/* Parse the arguments of recurse operations. */
+
+BOOL PRIV(compile_parse_recurse_args)(uint32_t *pptr_start,
+ PCRE2_SIZE offset, int *errorcodeptr, compile_block *cb);
+
#endif /* PCRE2_COMPILE_H_IDEMPOTENT_GUARD */
/* End of pcre2_compile.h */
diff --git a/src/3rdparty/pcre2/src/pcre2_compile_cgroup.c b/src/3rdparty/pcre2/src/pcre2_compile_cgroup.c
new file mode 100644
index 00000000000..ee0cd06b70a
--- /dev/null
+++ b/src/3rdparty/pcre2/src/pcre2_compile_cgroup.c
@@ -0,0 +1,632 @@
+/*************************************************
+* Perl-Compatible Regular Expressions *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+ Written by Philip Hazel
+ Original API code Copyright (c) 1997-2012 University of Cambridge
+ New API code Copyright (c) 2016-2024 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the name of the University of Cambridge nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+-----------------------------------------------------------------------------
+*/
+
+
+#include "pcre2_compile.h"
+
+/*************************************************
+* Compute the hash code from a capture name *
+*************************************************/
+
+/* This function returns with a simple hash code
+computed from the name of a capture group.
+
+Arguments:
+ name name of the capture group
+ length the length of the name
+
+Returns: hash code
+*/
+
+uint16_t
+PRIV(compile_get_hash_from_name)(PCRE2_SPTR name, uint32_t length)
+{
+uint16_t hash;
+
+PCRE2_ASSERT(length > 0);
+
+hash = (uint16_t)((name[0] & 0x7f) | ((name[length - 1] & 0xff) << 7));
+PCRE2_ASSERT(hash <= NAMED_GROUP_HASH_MASK);
+return hash;
+}
+
+
+/*************************************************
+* Get the descriptor of a known named capture *
+*************************************************/
+
+/* This function returns the descriptor in the
+named group list of a known capture group.
+
+Arguments:
+ name name of the capture group
+ length the length of the name
+
+Returns: pointer to the descriptor when found,
+ NULL otherwise
+ */
+
+named_group *
+PRIV(compile_find_named_group)(PCRE2_SPTR name,
+ uint32_t length, compile_block *cb)
+{
+uint16_t hash = PRIV(compile_get_hash_from_name)(name, length);
+named_group *ng;
+named_group *end = cb->named_groups + cb->names_found;
+
+for (ng = cb->named_groups; ng < end; ng++)
+ if (length == ng->length && hash == NAMED_GROUP_GET_HASH(ng) &&
+ PRIV(strncmp)(name, ng->name, length) == 0) return ng;
+
+return NULL;
+}
+
+
+/*************************************************
+* Add an entry to the name/number table *
+*************************************************/
+
+/* This function is called between compiling passes to add an entry to the
+name/number table, maintaining alphabetical order. Checking for permitted
+and forbidden duplicates has already been done.
+
+Arguments:
+ cb the compile data block
+ nb named group entry
+ tablecount the count of names in the table so far
+
+Returns: new tablecount
+*/
+
+uint32_t
+PRIV(compile_add_name_to_table)(compile_block *cb,
+ named_group *ng, uint32_t tablecount)
+{
+uint32_t i;
+PCRE2_SPTR name = ng->name;
+int length = ng->length;
+uint32_t duplicate_count = 1;
+
+PCRE2_UCHAR *slot = cb->name_table;
+
+PCRE2_ASSERT(length > 0);
+
+if ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0)
+ {
+ named_group *ng_it;
+ named_group *end = cb->named_groups + cb->names_found;
+
+ for (ng_it = ng + 1; ng_it < end; ng_it++)
+ if (ng_it->name == name) duplicate_count++;
+ }
+
+for (i = 0; i < tablecount; i++)
+ {
+ int crc = memcmp(name, slot + IMM2_SIZE, CU2BYTES(length));
+ if (crc == 0 && slot[IMM2_SIZE + length] != 0)
+ crc = -1; /* Current name is a substring */
+
+ /* Make space in the table and break the loop for an earlier name. For a
+ duplicate or later name, carry on. We do this for duplicates so that in the
+ simple case (when ?(| is not used) they are in order of their numbers. In all
+ cases they are in the order in which they appear in the pattern. */
+
+ if (crc < 0)
+ {
+ (void)memmove(slot + cb->name_entry_size * duplicate_count, slot,
+ CU2BYTES((tablecount - i) * cb->name_entry_size));
+ break;
+ }
+
+ /* Continue the loop for a later or duplicate name */
+
+ slot += cb->name_entry_size;
+ }
+
+tablecount += duplicate_count;
+
+while (TRUE)
+ {
+ PUT2(slot, 0, ng->number);
+ memcpy(slot + IMM2_SIZE, name, CU2BYTES(length));
+
+ /* Add a terminating zero and fill the rest of the slot with zeroes so that
+ the memory is all initialized. Otherwise valgrind moans about uninitialized
+ memory when saving serialized compiled patterns. */
+
+ memset(slot + IMM2_SIZE + length, 0,
+ CU2BYTES(cb->name_entry_size - length - IMM2_SIZE));
+
+ if (--duplicate_count == 0) break;
+
+ while (TRUE)
+ {
+ ++ng;
+ if (ng->name == name) break;
+ }
+
+ slot += cb->name_entry_size;
+ }
+
+return tablecount;
+}
+
+
+/*************************************************
+* Find details of duplicate group names *
+*************************************************/
+
+/* This is called from compile_branch() when it needs to know the index and
+count of duplicates in the names table when processing named backreferences,
+either directly, or as conditions.
+
+Arguments:
+ name points to the name
+ length the length of the name
+ indexptr where to put the index
+ countptr where to put the count of duplicates
+ errorcodeptr where to put an error code
+ cb the compile block
+
+Returns: TRUE if OK, FALSE if not, error code set
+*/
+
+BOOL
+PRIV(compile_find_dupname_details)(PCRE2_SPTR name, uint32_t length,
+ int *indexptr, int *countptr, int *errorcodeptr, compile_block *cb)
+{
+uint32_t i, groupnumber;
+int count;
+PCRE2_UCHAR *slot = cb->name_table;
+
+/* Find the first entry in the table */
+
+for (i = 0; i < cb->names_found; i++)
+ {
+ if (PRIV(strncmp)(name, slot + IMM2_SIZE, length) == 0 &&
+ slot[IMM2_SIZE + length] == 0) break;
+ slot += cb->name_entry_size;
+ }
+
+/* This should not occur, because this function is called only when we know we
+have duplicate names. Give an internal error. */
+
+/* LCOV_EXCL_START */
+if (i >= cb->names_found)
+ {
+ PCRE2_DEBUG_UNREACHABLE();
+ *errorcodeptr = ERR53;
+ cb->erroroffset = name - cb->start_pattern;
+ return FALSE;
+ }
+/* LCOV_EXCL_STOP */
+
+/* Record the index and then see how many duplicates there are, updating the
+backref map and maximum back reference as we do. */
+
+*indexptr = i;
+count = 0;
+
+for (;;)
+ {
+ count++;
+ groupnumber = GET2(slot, 0);
+ cb->backref_map |= (groupnumber < 32)? (1u << groupnumber) : 1;
+ if (groupnumber > cb->top_backref) cb->top_backref = groupnumber;
+ if (++i >= cb->names_found) break;
+ slot += cb->name_entry_size;
+ if (PRIV(strncmp)(name, slot + IMM2_SIZE, length) != 0 ||
+ (slot + IMM2_SIZE)[length] != 0) break;
+ }
+
+*countptr = count;
+return TRUE;
+}
+
+
+/* Process the capture list of scan substring and recurse
+operations. Since at least one argument must be present,
+a 0 return value represents error. */
+
+static size_t
+PRIV(compile_process_capture_list)(uint32_t *pptr, PCRE2_SIZE offset,
+ int *errorcodeptr, compile_block *cb)
+{
+size_t i, size = 0;
+named_group *ng;
+PCRE2_SPTR name;
+uint32_t length;
+named_group *end = cb->named_groups + cb->names_found;
+
+while (TRUE)
+ {
+ ++pptr;
+
+ switch (META_CODE(*pptr))
+ {
+ case META_OFFSET:
+ GETPLUSOFFSET(offset, pptr);
+ continue;
+
+ case META_CAPTURE_NAME:
+ offset += META_DATA(*pptr);
+ length = *(++pptr);
+ name = cb->start_pattern + offset;
+
+ ng = PRIV(compile_find_named_group)(name, length, cb);
+
+ if (ng == NULL)
+ {
+ *errorcodeptr = ERR15;
+ cb->erroroffset = offset;
+ return 0;
+ }
+
+ if ((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) == 0)
+ {
+ pptr[-1] = META_CAPTURE_NUMBER;
+ pptr[0] = ng->number;
+ size++;
+ continue;
+ }
+
+ /* Remains only for duplicated names. */
+ pptr[-1] = META_CAPTURE_NAME;
+ pptr[0] = (uint32_t)(ng - cb->named_groups);
+ size++;
+ name = ng->name;
+
+ while (++ng < end)
+ if (ng->name == name) size++;
+ continue;
+
+ case META_CAPTURE_NUMBER:
+ offset += META_DATA(*pptr);
+
+ i = *(++pptr);
+ if (i > cb->bracount)
+ {
+ *errorcodeptr = ERR15;
+ cb->erroroffset = offset;
+ return 0;
+ }
+ if (i > cb->top_backref) cb->top_backref = (uint16_t)i;
+ size++;
+ continue;
+
+ default:
+ break;
+ }
+
+ PCRE2_ASSERT(size > 0);
+ return size;
+ }
+}
+
+
+/*******************************************************
+* Parse the arguments of scan substring operations *
+********************************************************/
+
+/* This function parses the arguments of scan substring operations.
+
+Arguments:
+ pptr_start points to the current parsed pattern pointer
+ offset argument starting offset in the pattern
+ errorcodeptr where to put an error code
+ cb the compile block
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: TRUE if OK, FALSE if not, error code set
+*/
+
+uint32_t *
+PRIV(compile_parse_scan_substr_args)(uint32_t *pptr,
+ int *errorcodeptr, compile_block *cb, PCRE2_SIZE *lengthptr)
+{
+uint8_t *captures;
+uint8_t *capture_ptr;
+uint8_t bit;
+PCRE2_SPTR name;
+named_group *ng;
+named_group *end = cb->named_groups + cb->names_found;
+BOOL all_found;
+size_t size;
+
+PCRE2_ASSERT(*pptr == META_OFFSET);
+if (PRIV(compile_process_capture_list)(pptr - 1, 0, errorcodeptr, cb) == 0)
+ return NULL;
+
+/* Align to bytes. Since the highest capture can
+be equal to bracount, +1 is added before the aligning. */
+size = (cb->bracount + 1 + 7) >> 3;
+captures = (uint8_t*)cb->cx->memctl.malloc(size, cb->cx->memctl.memory_data);
+if (captures == NULL)
+ {
+ *errorcodeptr = ERR21;
+ READPLUSOFFSET(cb->erroroffset, pptr);
+ return NULL;
+ }
+
+memset(captures, 0, size);
+
+while (TRUE)
+ {
+ switch (META_CODE(*pptr))
+ {
+ case META_OFFSET:
+ pptr++;
+ SKIPOFFSET(pptr);
+ continue;
+
+ case META_CAPTURE_NAME:
+ ng = cb->named_groups + pptr[1];
+ PCRE2_ASSERT((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0);
+ pptr += 2;
+ name = ng->name;
+
+ all_found = TRUE;
+ do
+ {
+ if (ng->name != name) continue;
+
+ capture_ptr = captures + (ng->number >> 3);
+ PCRE2_ASSERT(capture_ptr < captures + size);
+ bit = (uint8_t)(1 << (ng->number & 0x7));
+
+ if ((*capture_ptr & bit) == 0)
+ {
+ *capture_ptr |= bit;
+ all_found = FALSE;
+ }
+ }
+ while (++ng < end);
+
+ if (!all_found)
+ {
+ *lengthptr += 1 + 2 * IMM2_SIZE;
+ continue;
+ }
+
+ pptr[-2] = META_CAPTURE_NUMBER;
+ pptr[-1] = 0;
+ continue;
+
+ case META_CAPTURE_NUMBER:
+ pptr += 2;
+
+ capture_ptr = captures + (pptr[-1] >> 3);
+ PCRE2_ASSERT(capture_ptr < captures + size);
+ bit = (uint8_t)(1 << (pptr[-1] & 0x7));
+
+ if ((*capture_ptr & bit) != 0)
+ {
+ pptr[-1] = 0;
+ continue;
+ }
+
+ *capture_ptr |= bit;
+ *lengthptr += 1 + IMM2_SIZE;
+ continue;
+
+ default:
+ break;
+ }
+
+ break;
+ }
+
+cb->cx->memctl.free(captures, cb->cx->memctl.memory_data);
+return pptr - 1;
+}
+
+
+/* Implement heapsort heapify algorithm. */
+
+static void do_heapify_u16(uint16_t *captures, size_t size, size_t i)
+{
+size_t max;
+size_t left;
+size_t right;
+uint16_t tmp;
+
+while (TRUE)
+ {
+ max = i;
+ left = (i << 1) + 1;
+ right = left + 1;
+
+ if (left < size && captures[left] > captures[max]) max = left;
+ if (right < size && captures[right] > captures[max]) max = right;
+ if (i == max) return;
+
+ tmp = captures[i];
+ captures[i] = captures[max];
+ captures[max] = tmp;
+ i = max;
+ }
+}
+
+
+/*************************************************
+* Parse the arguments of recurse operations *
+*************************************************/
+
+/* This function parses the arguments of recurse operations.
+
+Arguments:
+ pptr_start the current parsed pattern pointer
+ offset argument starting offset in the pattern
+ errorcodeptr where to put an error code
+ cb the compile block
+ lengthptr NULL during the real compile phase
+ points to length accumulator during pre-compile phase
+
+Returns: TRUE if OK, FALSE if not, error code set
+*/
+
+BOOL
+PRIV(compile_parse_recurse_args)(uint32_t *pptr_start,
+ PCRE2_SIZE offset, int *errorcodeptr, compile_block *cb)
+{
+uint32_t *pptr = pptr_start;
+size_t i, size;
+PCRE2_SPTR name;
+named_group *ng;
+named_group *end = cb->named_groups + cb->names_found;
+recurse_arguments *args;
+uint16_t *captures;
+uint16_t *current;
+uint16_t *captures_end;
+uint16_t tmp;
+
+/* Process all arguments, compute the required size. */
+
+size = PRIV(compile_process_capture_list)(pptr, offset, errorcodeptr, cb);
+if (size == 0) return FALSE;
+
+args = cb->cx->memctl.malloc(
+ sizeof(recurse_arguments) + size * sizeof(uint16_t), cb->cx->memctl.memory_data);
+
+if (args == NULL)
+ {
+ *errorcodeptr = ERR21;
+ cb->erroroffset = offset;
+ return FALSE;
+ }
+
+args->header.next = NULL;
+#ifdef PCRE2_DEBUG
+args->header.type = CDATA_RECURSE_ARGS;
+#endif
+args->size = size;
+
+/* Caching the pre-processed capture list. */
+if (cb->last_data != NULL)
+ cb->last_data->next = &args->header;
+else
+ cb->first_data = &args->header;
+
+cb->last_data = &args->header;
+
+/* Create the capture list size. */
+
+captures = (uint16_t*)(args + 1);
+
+while (TRUE)
+ {
+ ++pptr;
+
+ switch (META_CODE(*pptr))
+ {
+ case META_OFFSET:
+ SKIPOFFSET(pptr);
+ continue;
+
+ case META_CAPTURE_NAME:
+ ng = cb->named_groups + *(++pptr);
+ PCRE2_ASSERT((ng->hash_dup & NAMED_GROUP_IS_DUPNAME) != 0);
+ *captures++ = (uint16_t)(ng->number);
+
+ name = ng->name;
+
+ while (++ng < end)
+ if (ng->name == name) *captures++ = (uint16_t)(ng->number);
+ continue;
+
+ case META_CAPTURE_NUMBER:
+ *captures++ = *(++pptr);
+ continue;
+
+ default:
+ break;
+ }
+
+ break;
+ }
+
+PCRE2_ASSERT(size == (size_t)(captures - (uint16_t*)(args + 1)));
+args->skip_size = (size_t)(pptr - pptr_start) - 1;
+
+if (size == 1) return TRUE;
+
+/* Sort captures. */
+
+captures = (uint16_t*)(args + 1);
+i = (size >> 1) - 1;
+while (TRUE)
+ {
+ do_heapify_u16(captures, size, i);
+ if (i == 0) break;
+ i--;
+ }
+
+for (i = size - 1; i > 0; i--)
+ {
+ tmp = captures[0];
+ captures[0] = captures[i];
+ captures[i] = tmp;
+
+ do_heapify_u16(captures, i, 0);
+ }
+
+/* Remove duplicates. */
+
+captures_end = captures + size;
+tmp = *captures++;
+current = captures;
+
+while (current < captures_end)
+ {
+ if (*current != tmp)
+ {
+ tmp = *current;
+ *captures++ = tmp;
+ }
+
+ current++;
+ }
+
+args->size = (size_t)(captures - (uint16_t*)(args + 1));
+return TRUE;
+}
+
+/* End of pcre2_compile_cgroup.c */
diff --git a/src/3rdparty/pcre2/src/pcre2_compile_class.c b/src/3rdparty/pcre2/src/pcre2_compile_class.c
index 6a73bb9a71b..9a1fc022fff 100644
--- a/src/3rdparty/pcre2/src/pcre2_compile_class.c
+++ b/src/3rdparty/pcre2/src/pcre2_compile_class.c
@@ -38,12 +38,11 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include "pcre2_compile.h"
+
+
typedef struct {
/* Option bits for eclass. */
uint32_t options;
@@ -66,7 +65,7 @@ b) none of the cases here:
#define CLASS_END_CASES(meta) \
default: \
PCRE2_ASSERT((meta) <= META_END); \
- /* Fall through */ \
+ PCRE2_FALLTHROUGH /* Fall through */ \
case META_CLASS: \
case META_CLASS_NOT: \
case META_CLASS_EMPTY: \
@@ -525,6 +524,9 @@ if (xoptions & PCRE2_EXTRA_CASELESS_RESTRICT)
if (xoptions & PCRE2_EXTRA_TURKISH_CASING)
class_options |= PARSE_CLASS_TURKISH_UTF;
+#else
+(void)options; /* Avoid compiler warning. */
+(void)xoptions; /* Avoid compiler warning. */
#endif
/* Compute required space for the range. */
@@ -543,7 +545,10 @@ cranges = cb->cx->memctl.malloc(
if (cranges == NULL) return NULL;
-cranges->next = NULL;
+cranges->header.next = NULL;
+#ifdef PCRE2_DEBUG
+cranges->header.type = CDATA_CRANGE;
+#endif
cranges->range_list_size = (uint16_t)range_list_size;
cranges->char_lists_types = 0;
cranges->char_lists_size = 0;
@@ -905,6 +910,10 @@ uint8_t *classbits = cb->classbits.classbits;
uint32_t c, byte_start, byte_end;
uint32_t classbits_end = (end <= 0xff ? end : 0xff);
+#ifndef SUPPORT_UNICODE
+(void)xoptions; /* Avoid compiler warning. */
+#endif
+
/* If caseless matching is required, scan the range and process alternate
cases. In Unicode, there are 8-bit characters that have alternate cases that
are greater than 255 and vice-versa (though these may be ignored if caseless
@@ -1080,6 +1089,10 @@ BOOL utf = FALSE;
uint32_t xclass_props;
PCRE2_UCHAR *class_uchardata;
class_ranges* cranges;
+#else
+(void)has_bitmap; /* Avoid compiler warning. */
+(void)errorcodeptr; /* Avoid compiler warning. */
+(void)lengthptr; /* Avoid compiler warning. */
#endif
/* If an XClass contains a negative special such as \S, we need to flip the
@@ -1112,19 +1125,19 @@ if (utf)
}
/* Caching the pre-processed character ranges. */
- if (cb->next_cranges != NULL)
- cb->next_cranges->next = cranges;
+ if (cb->last_data != NULL)
+ cb->last_data->next = &cranges->header;
else
- cb->cranges = cranges;
+ cb->first_data = &cranges->header;
- cb->next_cranges = cranges;
+ cb->last_data = &cranges->header;
}
else
{
/* Reuse the pre-processed character ranges. */
- cranges = cb->cranges;
- PCRE2_ASSERT(cranges != NULL);
- cb->cranges = cranges->next;
+ cranges = (class_ranges*)cb->first_data;
+ PCRE2_ASSERT(cranges != NULL && cranges->header.type == CDATA_CRANGE);
+ cb->first_data = cranges->header.next;
}
if (cranges->range_list_size > 0)
@@ -1270,8 +1283,23 @@ while (TRUE)
value of 1 removes vertical space and 2 removes underscore. */
if (tabopt < 0) tabopt = -tabopt;
+#ifdef EBCDIC
+ {
+ uint8_t posix_vertical[4] = { CHAR_LF, CHAR_VT, CHAR_FF, CHAR_CR };
+ uint8_t posix_underscore = CHAR_UNDERSCORE;
+ uint8_t *chars = NULL;
+ int n = 0;
+
+ if (tabopt == 1) { chars = posix_vertical; n = 4; }
+ else if (tabopt == 2) { chars = &posix_underscore; n = 1; }
+
+ for (; n > 0; ++chars, --n)
+ pbits.classbits[*chars/8] &= ~(1u << (*chars&7));
+ }
+#else
if (tabopt == 1) pbits.classbits[1] &= ~0x3c;
- else if (tabopt == 2) pbits.classbits[11] &= 0x7f;
+ else if (tabopt == 2) pbits.classbits[11] &= 0x7f;
+#endif
/* Add the POSIX table or its complement into the main table that is
being built and we are done. */
@@ -2079,9 +2107,11 @@ switch (op)
lhs_op_info->bits.classwords[i] ^= rhs_op_info->bits.classwords[i];
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
break;
+ /* LCOV_EXCL_STOP */
}
}
@@ -2141,7 +2171,7 @@ switch (meta)
}
ptr++;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
default:
/* Scan forward characters, ranges, and properties.
@@ -2158,11 +2188,13 @@ switch (meta)
/* We must have a 100% guarantee that ptr increases when
compile_class_operand() returns, even on Release builds, so that we can
statically prove our loops terminate. */
+ /* LCOV_EXCL_START */
if (ptr <= prev_ptr)
{
PCRE2_DEBUG_UNREACHABLE();
return FALSE;
}
+ /* LCOV_EXCL_STOP */
/* If we fell through above, consume the closing ']'. */
if (meta == META_CLASS || meta == META_CLASS_NOT)
diff --git a/src/3rdparty/pcre2/src/pcre2_config.c b/src/3rdparty/pcre2/src/pcre2_config.c
index 031981b09bf..045f6e78d11 100644
--- a/src/3rdparty/pcre2/src/pcre2_config.c
+++ b/src/3rdparty/pcre2/src/pcre2_config.c
@@ -38,17 +38,10 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-/* Save the configured link size, which is in bytes. In 16-bit and 32-bit modes
-its value gets changed by pcre2_intmodedep.h (included by pcre2_internal.h) to
-be in code units. */
+#include "pcre2_internal.h"
-static int configured_link_size = LINK_SIZE;
-#include "pcre2_internal.h"
/* These macros are the standard way of turning unquoted text into C strings.
They allow macros like PCRE2_MAJOR to be defined without quotes, which is
@@ -79,7 +72,7 @@ pcre2_config(uint32_t what, void *where)
{
if (where == NULL) /* Requests a length */
{
- switch(what)
+ switch (what)
{
default:
return PCRE2_ERROR_BADOPTION;
@@ -87,6 +80,7 @@ if (where == NULL) /* Requests a length */
case PCRE2_CONFIG_BSR:
case PCRE2_CONFIG_COMPILED_WIDTHS:
case PCRE2_CONFIG_DEPTHLIMIT:
+ case PCRE2_CONFIG_EFFECTIVE_LINKSIZE:
case PCRE2_CONFIG_HEAPLIMIT:
case PCRE2_CONFIG_JIT:
case PCRE2_CONFIG_LINKSIZE:
@@ -124,13 +118,13 @@ switch (what)
case PCRE2_CONFIG_COMPILED_WIDTHS:
*((uint32_t *)where) = 0
#ifdef SUPPORT_PCRE2_8
- + 1
+ + (1 << 0)
#endif
#ifdef SUPPORT_PCRE2_16
- + 2
+ + (1 << 1)
#endif
#ifdef SUPPORT_PCRE2_32
- + 4
+ + (1 << 2)
#endif
;
break;
@@ -139,6 +133,10 @@ switch (what)
*((uint32_t *)where) = MATCH_LIMIT_DEPTH;
break;
+ case PCRE2_CONFIG_EFFECTIVE_LINKSIZE:
+ *((uint32_t *)where) = LINK_SIZE * sizeof(PCRE2_UCHAR);
+ break;
+
case PCRE2_CONFIG_HEAPLIMIT:
*((uint32_t *)where) = HEAP_LIMIT;
break;
@@ -163,7 +161,7 @@ switch (what)
#endif
case PCRE2_CONFIG_LINKSIZE:
- *((uint32_t *)where) = (uint32_t)configured_link_size;
+ *((uint32_t *)where) = (uint32_t)CONFIGURED_LINK_SIZE;
break;
case PCRE2_CONFIG_MATCHLIMIT:
@@ -206,8 +204,7 @@ switch (what)
#endif
return (int)(1 + ((where == NULL)?
strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
- }
- break;
+ }
case PCRE2_CONFIG_UNICODE:
#if defined SUPPORT_UNICODE
@@ -244,6 +241,7 @@ switch (what)
return (int)(1 + ((where == NULL)?
strlen(v) : PRIV(strcpy_c8)((PCRE2_UCHAR *)where, v)));
}
+
}
return 0;
diff --git a/src/3rdparty/pcre2/src/pcre2_context.c b/src/3rdparty/pcre2/src/pcre2_context.c
index 2345145d3f5..6246683df52 100644
--- a/src/3rdparty/pcre2/src/pcre2_context.c
+++ b/src/3rdparty/pcre2/src/pcre2_context.c
@@ -39,10 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
@@ -506,10 +502,7 @@ return 0;
}
/* These functions became obsolete at release 10.30. The first is kept as a
-synonym for backwards compatibility. The second now does nothing. Exclude both
-from coverage reports. */
-
-/* LCOV_EXCL_START */
+synonym for backwards compatibility. The second now does nothing. */
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_set_recursion_limit(pcre2_match_context *mcontext, uint32_t limit)
@@ -529,8 +522,6 @@ pcre2_set_recursion_memory_management(pcre2_match_context *mcontext,
return 0;
}
-/* LCOV_EXCL_STOP */
-
/* ------------ Convert context ------------ */
@@ -543,10 +534,20 @@ ccontext->glob_separator = separator;
return 0;
}
+static const char *globpunct =
+ STR_EXCLAMATION_MARK STR_QUOTATION_MARK STR_NUMBER_SIGN STR_DOLLAR_SIGN
+ STR_PERCENT_SIGN STR_AMPERSAND STR_APOSTROPHE STR_LEFT_PARENTHESIS
+ STR_RIGHT_PARENTHESIS STR_ASTERISK STR_PLUS STR_COMMA STR_MINUS STR_DOT
+ STR_SLASH STR_COLON STR_SEMICOLON STR_LESS_THAN_SIGN STR_EQUALS_SIGN
+ STR_GREATER_THAN_SIGN STR_QUESTION_MARK STR_COMMERCIAL_AT
+ STR_LEFT_SQUARE_BRACKET STR_BACKSLASH STR_RIGHT_SQUARE_BRACKET
+ STR_CIRCUMFLEX_ACCENT STR_UNDERSCORE STR_GRAVE_ACCENT STR_LEFT_CURLY_BRACKET
+ STR_VERTICAL_LINE STR_RIGHT_CURLY_BRACKET STR_TILDE;
+
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
pcre2_set_glob_escape(pcre2_convert_context *ccontext, uint32_t escape)
{
-if (escape > 255 || (escape != 0 && !ispunct(escape)))
+if (escape > 255 || (escape != 0 && strchr(globpunct, escape) == NULL))
return PCRE2_ERROR_BADDATA;
ccontext->glob_escape = escape;
return 0;
diff --git a/src/3rdparty/pcre2/src/pcre2_dfa_match.c b/src/3rdparty/pcre2/src/pcre2_dfa_match.c
index ebf31d284d2..f507acf8d59 100644
--- a/src/3rdparty/pcre2/src/pcre2_dfa_match.c
+++ b/src/3rdparty/pcre2/src/pcre2_dfa_match.c
@@ -72,16 +72,14 @@ Overall, I concluded that the gains in some cases did not outweigh the losses
in others, so I abandoned this code. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "pcre2_internal.h"
+
+
#define NLBLOCK mb /* Block containing newline information */
#define PSSTART start_subject /* Field containing processed string start */
#define PSEND end_subject /* Field containing processed string end */
-#include "pcre2_internal.h"
-
#define PUBLIC_DFA_MATCH_OPTIONS \
(PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \
PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \
@@ -2330,7 +2328,7 @@ for (;;)
case 0x2029:
#endif /* Not EBCDIC */
if (mb->bsr_convention == PCRE2_BSR_ANYCRLF) break;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case CHAR_LF:
ADD_NEW(state_offset + 1, 0);
@@ -2442,7 +2440,7 @@ for (;;)
caseless = TRUE;
codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
@@ -2486,7 +2484,7 @@ for (;;)
case OP_NOTPOSQUERYI:
caseless = TRUE;
codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_QUERY:
case OP_MINQUERY:
case OP_POSQUERY:
@@ -2527,7 +2525,7 @@ for (;;)
case OP_NOTPOSSTARI:
caseless = TRUE;
codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_STAR:
case OP_MINSTAR:
case OP_POSSTAR:
@@ -2564,7 +2562,7 @@ for (;;)
case OP_NOTEXACTI:
caseless = TRUE;
codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_EXACT:
case OP_NOTEXACT:
count = current_state->count; /* Number already matched */
@@ -2599,7 +2597,7 @@ for (;;)
case OP_NOTPOSUPTOI:
caseless = TRUE;
codevalue -= OP_STARI - OP_STAR;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_UPTO:
case OP_MINUPTO:
case OP_POSUPTO:
@@ -2941,6 +2939,9 @@ for (;;)
uint32_t recno = (callpat == mb->start_code)? 0 :
GET2(callpat, 1 + LINK_SIZE);
+ /* Argument list has not been supported yet. */
+ if (code[1 + LINK_SIZE] == OP_CREF) return PCRE2_ERROR_DFA_UITEM;
+
if (rws->free < RWS_RSIZE + RWS_OVEC_RSIZE)
{
rc = more_workspace(&rws, RWS_OVEC_RSIZE, mb);
@@ -3341,10 +3342,12 @@ pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount)
{
int rc;
-int was_zero_terminated = 0;
const pcre2_real_code *re = (const pcre2_real_code *)code;
+uint32_t original_options = options;
+PCRE2_UCHAR null_str[1] = { 0xcd };
+PCRE2_SPTR original_subject = subject;
PCRE2_SPTR start_match;
PCRE2_SPTR end_subject;
PCRE2_SPTR bumpalong_limit;
@@ -3386,44 +3389,46 @@ rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE;
/* Recognize NULL, length 0 as an empty string. */
-if (subject == NULL && length == 0) subject = (PCRE2_SPTR)"";
+if (subject == NULL && length == 0) subject = null_str;
/* Plausibility checks */
-if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
-if (re == NULL || subject == NULL || workspace == NULL || match_data == NULL)
- return PCRE2_ERROR_NULL;
+if (match_data == NULL) return PCRE2_ERROR_NULL;
+if (re == NULL || subject == NULL || workspace == NULL)
+ { rc = PCRE2_ERROR_NULL; goto EXIT; }
+if ((options & ~PUBLIC_DFA_MATCH_OPTIONS) != 0)
+ { rc = PCRE2_ERROR_BADOPTION; goto EXIT; }
if (length == PCRE2_ZERO_TERMINATED)
{
length = PRIV(strlen)(subject);
- was_zero_terminated = 1;
}
-if (wscount < 20) return PCRE2_ERROR_DFA_WSSIZE;
-if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
+if (wscount < 20) { rc = PCRE2_ERROR_DFA_WSSIZE; goto EXIT; }
+if (start_offset > length) { rc = PCRE2_ERROR_BADOFFSET; goto EXIT; }
/* Partial matching and PCRE2_ENDANCHORED are currently not allowed at the same
time. */
if ((options & (PCRE2_PARTIAL_HARD|PCRE2_PARTIAL_SOFT)) != 0 &&
((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
- return PCRE2_ERROR_BADOPTION;
+ { rc = PCRE2_ERROR_BADOPTION; goto EXIT; }
/* Invalid UTF support is not available for DFA matching. */
if ((re->overall_options & PCRE2_MATCH_INVALID_UTF) != 0)
- return PCRE2_ERROR_DFA_UINVALID_UTF;
+ { rc = PCRE2_ERROR_DFA_UINVALID_UTF; goto EXIT; }
/* Check that the first field in the block is the magic number. If it is not,
return with PCRE2_ERROR_BADMAGIC. */
-if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+if (re->magic_number != MAGIC_NUMBER)
+ { rc = PCRE2_ERROR_BADMAGIC; goto EXIT; }
/* Check the code unit width. */
if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
- return PCRE2_ERROR_BADMODE;
+ { rc = PCRE2_ERROR_BADMODE; goto EXIT; }
/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
options variable for this function. Users of PCRE2 who are not calling the
@@ -3449,8 +3454,8 @@ of the workspace. */
if ((options & PCRE2_DFA_RESTART) != 0)
{
if ((workspace[0] & (-2)) != 0 || workspace[1] < 1 ||
- workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))
- return PCRE2_ERROR_DFA_BADRESTART;
+ workspace[1] > (int)((wscount - 2)/INTS_PER_STATEBLOCK))
+ { rc = PCRE2_ERROR_DFA_BADRESTART; goto EXIT; }
}
/* Set some local values */
@@ -3498,7 +3503,7 @@ else
if (mcontext->offset_limit != PCRE2_UNSET)
{
if ((re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
- return PCRE2_ERROR_BADOFFSETLIMIT;
+ { rc = PCRE2_ERROR_BADOFFSETLIMIT; goto EXIT; }
bumpalong_limit = subject + mcontext->offset_limit;
}
mb->callout = mcontext->callout;
@@ -3565,9 +3570,12 @@ switch(re->newline_convention)
mb->nltype = NLTYPE_ANYCRLF;
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
- return PCRE2_ERROR_INTERNAL;
+ rc = PCRE2_ERROR_INTERNAL;
+ goto EXIT;
+ /* LCOV_EXCL_STOP */
}
/* Check a UTF string for validity if required. For 8-bit and 16-bit strings,
@@ -3588,7 +3596,7 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
#if PCRE2_CODE_UNIT_WIDTH != 32
unsigned int i;
if (start_match < end_subject && NOT_FIRSTCU(*start_match))
- return PCRE2_ERROR_BADUTFOFFSET;
+ { rc = PCRE2_ERROR_BADUTFOFFSET; goto EXIT; }
for (i = re->max_lookbehind; i > 0 && check_subject > subject; i--)
{
check_subject--;
@@ -3609,12 +3617,12 @@ if (utf && (options & PCRE2_NO_UTF_CHECK) == 0)
/* Validate the relevant portion of the subject. After an error, adjust the
offset to be an absolute offset in the whole string. */
- match_data->rc = PRIV(valid_utf)(check_subject,
+ rc = PRIV(valid_utf)(check_subject,
length - (PCRE2_SIZE)(check_subject - subject), &(match_data->startchar));
- if (match_data->rc != 0)
+ if (rc != 0)
{
match_data->startchar += (PCRE2_SIZE)(check_subject - subject);
- return match_data->rc;
+ goto EXIT;
}
}
#endif /* SUPPORT_UNICODE */
@@ -3678,9 +3686,10 @@ if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
/* Fill in fields that are always returned in the match data. */
match_data->code = re;
-match_data->subject = NULL; /* Default for no match */
+match_data->subject = NULL; /* Default for match error */
match_data->mark = NULL;
match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER;
+match_data->options = original_options;
/* Call the main matching function, looping for a non-anchored regex after a
failed match. If not restarting, perform certain optimizations at the start of
@@ -4032,29 +4041,40 @@ for (;;)
if (rc != PCRE2_ERROR_NOMATCH || anchored)
{
+ if (rc == PCRE2_ERROR_NOMATCH) goto NOMATCH_EXIT;
+
if (rc == PCRE2_ERROR_PARTIAL && match_data->oveccount > 0)
{
match_data->ovector[0] = (PCRE2_SIZE)(start_match - subject);
match_data->ovector[1] = (PCRE2_SIZE)(end_subject - subject);
}
- match_data->subject_length = length;
- match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
- match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject);
- match_data->startchar = (PCRE2_SIZE)(start_match - subject);
- match_data->rc = rc;
- if (rc >= 0 &&(options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
+ if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)
+ {
+ match_data->subject_length = length;
+ match_data->start_offset = start_offset;
+ match_data->leftchar = (PCRE2_SIZE)(mb->start_used_ptr - subject);
+ match_data->rightchar = (PCRE2_SIZE)(mb->last_used_ptr - subject);
+ match_data->startchar = (PCRE2_SIZE)(start_match - subject);
+ }
+
+ if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
{
- length = CU2BYTES(length + was_zero_terminated);
- match_data->subject = match_data->memctl.malloc(length,
- match_data->memctl.memory_data);
- if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy((void *)match_data->subject, subject, length);
+ if (length != 0)
+ {
+ match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
+ match_data->memctl.memory_data);
+ if (match_data->subject == NULL)
+ { rc = PCRE2_ERROR_NOMEMORY; goto EXIT; }
+ memcpy((void *)match_data->subject, subject, CU2BYTES(length));
+ }
+ else
+ match_data->subject = NULL;
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
}
- else
+ else if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)
{
- if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL) match_data->subject = subject;
+ match_data->subject = original_subject;
}
goto EXIT;
}
@@ -4088,6 +4108,9 @@ for (;;)
} /* "Bumpalong" loop */
NOMATCH_EXIT:
+match_data->subject = original_subject;
+match_data->subject_length = length;
+match_data->start_offset = start_offset;
rc = PCRE2_ERROR_NOMATCH;
EXIT:
@@ -4098,6 +4121,7 @@ while (rws->next != NULL)
mb->memctl.free(next, mb->memctl.memory_data);
}
+match_data->rc = rc;
return rc;
}
diff --git a/src/3rdparty/pcre2/src/pcre2_error.c b/src/3rdparty/pcre2/src/pcre2_error.c
index 8b7423c6c64..df26add2be9 100644
--- a/src/3rdparty/pcre2/src/pcre2_error.c
+++ b/src/3rdparty/pcre2/src/pcre2_error.c
@@ -39,12 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
+
+
#define STRING(a) # a
#define XSTRING(s) STRING(s)
@@ -97,7 +95,7 @@ static const unsigned char compile_error_texts[] =
"a relative value of zero is not allowed\0"
"conditional subpattern contains more than two branches\0"
"atomic assertion expected after (?( or (?(?C)\0"
- "digit expected after (?+ or (?-\0"
+ "digit expected after (?+\0"
/* 30 */
"unknown POSIX class name\0"
"internal error in pcre2_study(): should not occur\0"
@@ -148,7 +146,7 @@ static const unsigned char compile_error_texts[] =
#ifndef EBCDIC
"\\c must be followed by a printable ASCII character\0"
#else
- "\\c must be followed by a letter or one of [\\]^_?\0"
+ "\\c must be followed by a letter or one of @[\\]^_?\0"
#endif
"\\k is not followed by a braced, angle-bracketed, or quoted name\0"
/* 70 */
@@ -208,6 +206,11 @@ static const unsigned char compile_error_texts[] =
/* 115 */
"terminating ] with no following closing parenthesis in (?[...]\0"
"unexpected character in (?[...]) extended character class\0"
+ "expected capture group number or name\0"
+ "missing opening parenthesis\0"
+ "syntax error in subpattern number (missing terminator?)\0"
+ /* 120 */
+ "erroroffset passed as NULL\0"
;
/* Match-time and UTF error texts are in the same format. */
@@ -291,13 +294,18 @@ static const unsigned char match_error_texts[] =
"heap limit exceeded\0"
"invalid syntax\0"
/* 65 */
- "internal error - duplicate substitution match\0"
+ "internal error: duplicate substitution match\0"
"PCRE2_MATCH_INVALID_UTF is not supported for DFA matching\0"
- "INTERNAL ERROR: invalid substring offset\0"
+ "internal error: invalid substring offset\0"
"feature is not supported by the JIT compiler\0"
"error performing replacement case transformation\0"
/* 70 */
"replacement too large (longer than PCRE2_SIZE)\0"
+ "substitute pattern differs from prior match call\0"
+ "substitute subject differs from prior match call\0"
+ "substitute start offset differs from prior match call\0"
+ "substitute options differ from prior match call\0"
+ "disallowed use of \\K in lookaround\0"
;
@@ -324,7 +332,7 @@ pcre2_get_error_message(int enumber, PCRE2_UCHAR *buffer, PCRE2_SIZE size)
{
const unsigned char *message;
PCRE2_SIZE i;
-int n;
+int n, rc = 0;
if (size == 0) return PCRE2_ERROR_NOMEMORY;
@@ -346,7 +354,7 @@ else /* Invalid error number */
for (; n > 0; n--)
{
- while (*message++ != CHAR_NUL) {};
+ while (*message++ != CHAR_NUL) {}
if (*message == CHAR_NUL) return PCRE2_ERROR_BADDATA;
}
@@ -354,14 +362,23 @@ for (i = 0; *message != 0; i++)
{
if (i >= size - 1)
{
- buffer[i] = 0; /* Terminate partial message */
- return PCRE2_ERROR_NOMEMORY;
+ rc = PCRE2_ERROR_NOMEMORY;
+ break;
}
buffer[i] = *message++;
}
-buffer[i] = 0;
-return (int)i;
+#if defined EBCDIC && 'a' != 0x81
+/* If compiling for EBCDIC, but the compiler's string literals are not EBCDIC,
+then we are in the "force EBCDIC 1047" mode. I have chosen to add a few lines
+here to translate the error strings on the fly, rather than require the string
+literals above to be written out arduously using the "STR_XYZ" macros. */
+for (PCRE2_SIZE j = 0; j < i; ++j)
+ buffer[j] = PRIV(ascii_to_ebcdic_1047)[buffer[j]];
+#endif
+
+buffer[i] = 0; /* Terminate message, even if truncated. */
+return rc? rc : (int)i;
}
/* End of pcre2_error.c */
diff --git a/src/3rdparty/pcre2/src/pcre2_extuni.c b/src/3rdparty/pcre2/src/pcre2_extuni.c
index 91d839e2970..1b7f04b4b2f 100644
--- a/src/3rdparty/pcre2/src/pcre2_extuni.c
+++ b/src/3rdparty/pcre2/src/pcre2_extuni.c
@@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains an internal function that is used to match a Unicode
extended grapheme sequence. It is used by both pcre2_match() and
pcre2_dfa_match(). However, it is called only when Unicode support is being
@@ -45,14 +46,10 @@ compiled. Nevertheless, we provide a dummy function when there is no Unicode
support, because some compilers do not like functionless source files. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
#include "pcre2_internal.h"
+
/* Dummy function */
#ifndef SUPPORT_UNICODE
diff --git a/src/3rdparty/pcre2/src/pcre2_find_bracket.c b/src/3rdparty/pcre2/src/pcre2_find_bracket.c
index 486f4539d89..e26ee9923fe 100644
--- a/src/3rdparty/pcre2/src/pcre2_find_bracket.c
+++ b/src/3rdparty/pcre2/src/pcre2_find_bracket.c
@@ -46,13 +46,10 @@ function is called from pcre2_compile.c and also from pcre2_study.c when
finding the minimum matching length. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
+
/*************************************************
* Scan compiled regex for specific bracket *
*************************************************/
diff --git a/src/3rdparty/pcre2/src/pcre2_internal.h b/src/3rdparty/pcre2/src/pcre2_internal.h
index 6e0a5e05d03..aa79409572e 100644
--- a/src/3rdparty/pcre2/src/pcre2_internal.h
+++ b/src/3rdparty/pcre2/src/pcre2_internal.h
@@ -41,6 +41,15 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef PCRE2_INTERNAL_H_IDEMPOTENT_GUARD
#define PCRE2_INTERNAL_H_IDEMPOTENT_GUARD
+/* We do not assume that the config.h file has an idempotent include guard,
+since it may well be written by clients. The standard Autoheader config.h does
+not have an include guard (although we could customise that). */
+
+#if defined HAVE_CONFIG_H && !defined PCRE2_CONFIG_H_IDEMPOTENT_GUARD
+#define PCRE2_CONFIG_H_IDEMPOTENT_GUARD
+#include "config.h"
+#endif
+
/* We do not support both EBCDIC and Unicode at the same time. The "configure"
script prevents both being selected, but not everybody uses "configure". EBCDIC
is only supported for the 8-bit library, but the check for this has to be later
@@ -59,13 +68,12 @@ be including this file. There is no explicit way of forcing a compile to be
abandoned, but trying to include a non-existent file seems cleanest. Otherwise
there will be many irrelevant consequential errors. */
-#if (!defined PCRE2_BUILDING_PCRE2TEST && !defined PCRE2_DFTABLES) && \
+#if (!defined PCRE2_PCRE2TEST && !defined PCRE2_DFTABLES) && \
(!defined PCRE2_CODE_UNIT_WIDTH || \
(PCRE2_CODE_UNIT_WIDTH != 8 && \
PCRE2_CODE_UNIT_WIDTH != 16 && \
PCRE2_CODE_UNIT_WIDTH != 32))
#error PCRE2_CODE_UNIT_WIDTH must be defined as 8, 16, or 32.
-#include <AbandonCompile>
#endif
@@ -120,13 +128,12 @@ MSVC 10/2010. Except for VC6 (which is missing some fundamentals and fails). */
#endif
/* When compiling a DLL for Windows, the exported symbols have to be declared
-using some MS magic. I found some useful information on this web page:
-http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
-information there, using __declspec(dllexport) without "extern" we have a
-definition; with "extern" we have a declaration. The settings here override the
-setting in pcre2.h (which is included below); it defines only PCRE2_EXP_DECL,
-which is all that is needed for applications (they just import the symbols). We
-use:
+using some MS magic, as documented here:
+https://learn.microsoft.com/en-us/cpp/build/exporting-from-a-dll-using-declspec-dllexport
+
+In pcre2.h (which is included below), we define only PCRE2_EXP_DECL,
+which is all that is needed for applications (they just import the symbols). To
+compile the library, we use:
PCRE2_EXP_DECL for declarations
PCRE2_EXP_DEFN for definitions
@@ -140,24 +147,23 @@ special-purpose environments) might want to stick other stuff in front of
exported symbols. That's why, in the non-Windows case, we set PCRE2_EXP_DEFN
only if it is not already set. */
+#if defined __cplusplus
+#error This project uses C99. C++ is not supported.
+#endif
+
#ifndef PCRE2_EXP_DECL
-# ifdef _WIN32
-# ifndef PCRE2_STATIC
-# define PCRE2_EXP_DECL extern __declspec(dllexport)
-# define PCRE2_EXP_DEFN __declspec(dllexport)
-# else
-# define PCRE2_EXP_DECL extern PCRE2_EXPORT
-# define PCRE2_EXP_DEFN
-# endif
+# if defined(_WIN32) && !defined(PCRE2_STATIC)
+# define PCRE2_EXP_DECL extern __declspec(dllexport)
# else
-# ifdef __cplusplus
-# define PCRE2_EXP_DECL extern "C" PCRE2_EXPORT
-# else
-# define PCRE2_EXP_DECL extern PCRE2_EXPORT
-# endif
-# ifndef PCRE2_EXP_DEFN
-# define PCRE2_EXP_DEFN PCRE2_EXP_DECL
-# endif
+# define PCRE2_EXP_DECL extern PCRE2_EXPORT
+# endif
+#endif
+
+#ifndef PCRE2_EXP_DEFN
+# if defined(_WIN32) && !defined(PCRE2_STATIC)
+# define PCRE2_EXP_DEFN extern __declspec(dllexport)
+# else
+# define PCRE2_EXP_DEFN extern PCRE2_EXPORT
# endif
#endif
@@ -167,19 +173,6 @@ property values. This must follow the setting of PCRE2_EXP_DECL above. */
#include "pcre2.h"
#include "pcre2_ucp.h"
-/* When PCRE2 is compiled as a C++ library, the subject pointer can be replaced
-with a custom type. This makes it possible, for example, to allow pcre2_match()
-to process subject strings that are discontinuous by using a smart pointer
-class. It must always be possible to inspect all of the subject string in
-pcre2_match() because of the way it backtracks. */
-
-/* WARNING: This is as yet untested for PCRE2. */
-
-#ifdef CUSTOM_SUBJECT_PTR
-#undef PCRE2_SPTR
-#define PCRE2_SPTR CUSTOM_SUBJECT_PTR
-#endif
-
/* When checking for integer overflow, we need to handle large integers.
If a 64-bit integer type is available, we can use that.
Otherwise we have to cast to double, which of course requires floating point
@@ -201,28 +194,6 @@ code that a non-static object is being referenced. */
#define PRIV(name) _pcre2_##name
#endif
-/* When compiling for use with the Virtual Pascal compiler, these functions
-need to have their names changed. PCRE2 must be compiled with the -DVPCOMPAT
-option on the command line. */
-
-#ifdef VPCOMPAT
-#define strlen(s) _strlen(s)
-#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
-#define memcmp(s,c,n) _memcmp(s,c,n)
-#define memcpy(d,s,n) _memcpy(d,s,n)
-#define memmove(d,s,n) _memmove(d,s,n)
-#define memset(s,c,n) _memset(s,c,n)
-#else /* VPCOMPAT */
-
-/* Otherwise, to cope with SunOS4 and other systems that lack memmove(), define
-a macro that calls an emulating function. */
-
-#ifndef HAVE_MEMMOVE
-#undef memmove /* Some systems may have a macro */
-#define memmove(a, b, c) PRIV(memmove)(a, b, c)
-#endif /* not HAVE_MEMMOVE */
-#endif /* not VPCOMPAT */
-
/* This is an unsigned int value that no UTF character can ever have, as
Unicode doesn't go beyond 0x0010ffff. */
@@ -406,7 +377,7 @@ PCRE (both APIs) for a long time. */
#define HSPACE_LIST \
CHAR_HT, CHAR_SPACE, CHAR_NBSP, \
0x1680, 0x180e, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, \
- 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202f, 0x205f, 0x3000, \
+ 0x2006, 0x2007, 0x2008, 0x2009, 0x200a, 0x202f, 0x205f, 0x3000, \
NOTACHAR
#define HSPACE_MULTIBYTE_CASES \
@@ -422,7 +393,7 @@ PCRE (both APIs) for a long time. */
case 0x2007: /* FIGURE SPACE */ \
case 0x2008: /* PUNCTUATION SPACE */ \
case 0x2009: /* THIN SPACE */ \
- case 0x200A: /* HAIR SPACE */ \
+ case 0x200a: /* HAIR SPACE */ \
case 0x202f: /* NARROW NO-BREAK SPACE */ \
case 0x205f: /* MEDIUM MATHEMATICAL SPACE */ \
case 0x3000 /* IDEOGRAPHIC SPACE */
@@ -552,6 +523,7 @@ bytes in a code unit in that mode. */
#define PCRE2_DUPCAPUSED 0x00200000u /* contains (?| */
#define PCRE2_HASBKC 0x00400000u /* contains \C */
#define PCRE2_HASACCEPT 0x00800000u /* contains (*ACCEPT) */
+#define PCRE2_HASBSK 0x01000000u /* contains \K */
#define PCRE2_MODE_MASK (PCRE2_MODE8 | PCRE2_MODE16 | PCRE2_MODE32)
@@ -698,6 +670,10 @@ same code point. */
compatibility. NEL is the Unicode newline character; make sure it is
a positive value. */
+#if '\n' != 0x0a
+#error "ASCII character '\n' is not 0x0a"
+#endif
+
#define CHAR_LF '\n'
#define CHAR_NL CHAR_LF
#define CHAR_NEL ((unsigned char)'\x85')
@@ -713,7 +689,232 @@ a positive value. */
#endif /* EBCDIC */
-/* The remaining definitions work in both environments. */
+/* When we want to use EBCDIC with an ASCII compiler, for testing EBCDIC on
+ASCII platforms, then we can hardcode an EBCDIC codepage (IBM-1047). */
+
+#ifdef EBCDIC_IGNORING_COMPILER
+
+#define CHAR_NUL '\000'
+#define CHAR_HT '\005'
+#define CHAR_VT '\013'
+#define CHAR_FF '\014'
+#define CHAR_CR '\015'
+#define CHAR_BS '\026'
+#define CHAR_BEL '\057'
+
+#define CHAR_SPACE '\100'
+#define CHAR_EXCLAMATION_MARK '\132'
+#define CHAR_QUOTATION_MARK '\177'
+#define CHAR_NUMBER_SIGN '\173'
+#define CHAR_DOLLAR_SIGN '\133'
+#define CHAR_PERCENT_SIGN '\154'
+#define CHAR_AMPERSAND '\120'
+#define CHAR_APOSTROPHE '\175'
+#define CHAR_LEFT_PARENTHESIS '\115'
+#define CHAR_RIGHT_PARENTHESIS '\135'
+#define CHAR_ASTERISK '\134'
+#define CHAR_PLUS '\116'
+#define CHAR_COMMA '\153'
+#define CHAR_MINUS '\140'
+#define CHAR_DOT '\113'
+#define CHAR_SLASH '\141'
+#define CHAR_0 ((unsigned char)'\xf0')
+#define CHAR_1 ((unsigned char)'\xf1')
+#define CHAR_2 ((unsigned char)'\xf2')
+#define CHAR_3 ((unsigned char)'\xf3')
+#define CHAR_4 ((unsigned char)'\xf4')
+#define CHAR_5 ((unsigned char)'\xf5')
+#define CHAR_6 ((unsigned char)'\xf6')
+#define CHAR_7 ((unsigned char)'\xf7')
+#define CHAR_8 ((unsigned char)'\xf8')
+#define CHAR_9 ((unsigned char)'\xf9')
+#define CHAR_COLON '\172'
+#define CHAR_SEMICOLON '\136'
+#define CHAR_LESS_THAN_SIGN '\114'
+#define CHAR_EQUALS_SIGN '\176'
+#define CHAR_GREATER_THAN_SIGN '\156'
+#define CHAR_QUESTION_MARK '\157'
+#define CHAR_COMMERCIAL_AT '\174'
+#define CHAR_A ((unsigned char)'\xc1')
+#define CHAR_B ((unsigned char)'\xc2')
+#define CHAR_C ((unsigned char)'\xc3')
+#define CHAR_D ((unsigned char)'\xc4')
+#define CHAR_E ((unsigned char)'\xc5')
+#define CHAR_F ((unsigned char)'\xc6')
+#define CHAR_G ((unsigned char)'\xc7')
+#define CHAR_H ((unsigned char)'\xc8')
+#define CHAR_I ((unsigned char)'\xc9')
+#define CHAR_J ((unsigned char)'\xd1')
+#define CHAR_K ((unsigned char)'\xd2')
+#define CHAR_L ((unsigned char)'\xd3')
+#define CHAR_M ((unsigned char)'\xd4')
+#define CHAR_N ((unsigned char)'\xd5')
+#define CHAR_O ((unsigned char)'\xd6')
+#define CHAR_P ((unsigned char)'\xd7')
+#define CHAR_Q ((unsigned char)'\xd8')
+#define CHAR_R ((unsigned char)'\xd9')
+#define CHAR_S ((unsigned char)'\xe2')
+#define CHAR_T ((unsigned char)'\xe3')
+#define CHAR_U ((unsigned char)'\xe4')
+#define CHAR_V ((unsigned char)'\xe5')
+#define CHAR_W ((unsigned char)'\xe6')
+#define CHAR_X ((unsigned char)'\xe7')
+#define CHAR_Y ((unsigned char)'\xe8')
+#define CHAR_Z ((unsigned char)'\xe9')
+#define CHAR_LEFT_SQUARE_BRACKET ((unsigned char)'\xad')
+#define CHAR_BACKSLASH ((unsigned char)'\xe0')
+#define CHAR_RIGHT_SQUARE_BRACKET ((unsigned char)'\xbd')
+#define CHAR_CIRCUMFLEX_ACCENT '\137'
+#define CHAR_UNDERSCORE '\155'
+#define CHAR_GRAVE_ACCENT '\171'
+#define CHAR_a ((unsigned char)'\x81')
+#define CHAR_b ((unsigned char)'\x82')
+#define CHAR_c ((unsigned char)'\x83')
+#define CHAR_d ((unsigned char)'\x84')
+#define CHAR_e ((unsigned char)'\x85')
+#define CHAR_f ((unsigned char)'\x86')
+#define CHAR_g ((unsigned char)'\x87')
+#define CHAR_h ((unsigned char)'\x88')
+#define CHAR_i ((unsigned char)'\x89')
+#define CHAR_j ((unsigned char)'\x91')
+#define CHAR_k ((unsigned char)'\x92')
+#define CHAR_l ((unsigned char)'\x93')
+#define CHAR_m ((unsigned char)'\x94')
+#define CHAR_n ((unsigned char)'\x95')
+#define CHAR_o ((unsigned char)'\x96')
+#define CHAR_p ((unsigned char)'\x97')
+#define CHAR_q ((unsigned char)'\x98')
+#define CHAR_r ((unsigned char)'\x99')
+#define CHAR_s ((unsigned char)'\xa2')
+#define CHAR_t ((unsigned char)'\xa3')
+#define CHAR_u ((unsigned char)'\xa4')
+#define CHAR_v ((unsigned char)'\xa5')
+#define CHAR_w ((unsigned char)'\xa6')
+#define CHAR_x ((unsigned char)'\xa7')
+#define CHAR_y ((unsigned char)'\xa8')
+#define CHAR_z ((unsigned char)'\xa9')
+#define CHAR_LEFT_CURLY_BRACKET ((unsigned char)'\xc0')
+#define CHAR_VERTICAL_LINE '\117'
+#define CHAR_RIGHT_CURLY_BRACKET ((unsigned char)'\xd0')
+#define CHAR_TILDE ((unsigned char)'\xa1')
+
+#define STR_HT "\005"
+#define STR_VT "\013"
+#define STR_FF "\014"
+#define STR_CR "\015"
+#define STR_BS "\026"
+#define STR_BEL "\057"
+
+#define STR_SPACE "\100"
+#define STR_EXCLAMATION_MARK "\132"
+#define STR_QUOTATION_MARK "\177"
+#define STR_NUMBER_SIGN "\173"
+#define STR_DOLLAR_SIGN "\133"
+#define STR_PERCENT_SIGN "\154"
+#define STR_AMPERSAND "\120"
+#define STR_APOSTROPHE "\175"
+#define STR_LEFT_PARENTHESIS "\115"
+#define STR_RIGHT_PARENTHESIS "\135"
+#define STR_ASTERISK "\134"
+#define STR_PLUS "\116"
+#define STR_COMMA "\153"
+#define STR_MINUS "\140"
+#define STR_DOT "\113"
+#define STR_SLASH "\141"
+#define STR_0 "\360"
+#define STR_1 "\361"
+#define STR_2 "\362"
+#define STR_3 "\363"
+#define STR_4 "\364"
+#define STR_5 "\365"
+#define STR_6 "\366"
+#define STR_7 "\367"
+#define STR_8 "\370"
+#define STR_9 "\371"
+#define STR_COLON "\172"
+#define STR_SEMICOLON "\136"
+#define STR_LESS_THAN_SIGN "\114"
+#define STR_EQUALS_SIGN "\176"
+#define STR_GREATER_THAN_SIGN "\156"
+#define STR_QUESTION_MARK "\157"
+#define STR_COMMERCIAL_AT "\174"
+#define STR_A "\301"
+#define STR_B "\302"
+#define STR_C "\303"
+#define STR_D "\304"
+#define STR_E "\305"
+#define STR_F "\306"
+#define STR_G "\307"
+#define STR_H "\310"
+#define STR_I "\311"
+#define STR_J "\321"
+#define STR_K "\322"
+#define STR_L "\323"
+#define STR_M "\324"
+#define STR_N "\325"
+#define STR_O "\326"
+#define STR_P "\327"
+#define STR_Q "\330"
+#define STR_R "\331"
+#define STR_S "\342"
+#define STR_T "\343"
+#define STR_U "\344"
+#define STR_V "\345"
+#define STR_W "\346"
+#define STR_X "\347"
+#define STR_Y "\350"
+#define STR_Z "\351"
+#define STR_LEFT_SQUARE_BRACKET "\255"
+#define STR_BACKSLASH "\340"
+#define STR_RIGHT_SQUARE_BRACKET "\275"
+#define STR_CIRCUMFLEX_ACCENT "\137"
+#define STR_UNDERSCORE "\155"
+#define STR_GRAVE_ACCENT "\171"
+#define STR_a "\201"
+#define STR_b "\202"
+#define STR_c "\203"
+#define STR_d "\204"
+#define STR_e "\205"
+#define STR_f "\206"
+#define STR_g "\207"
+#define STR_h "\210"
+#define STR_i "\211"
+#define STR_j "\221"
+#define STR_k "\222"
+#define STR_l "\223"
+#define STR_m "\224"
+#define STR_n "\225"
+#define STR_o "\226"
+#define STR_p "\227"
+#define STR_q "\230"
+#define STR_r "\231"
+#define STR_s "\242"
+#define STR_t "\243"
+#define STR_u "\244"
+#define STR_v "\245"
+#define STR_w "\246"
+#define STR_x "\247"
+#define STR_y "\250"
+#define STR_z "\251"
+#define STR_LEFT_CURLY_BRACKET "\300"
+#define STR_VERTICAL_LINE "\117"
+#define STR_RIGHT_CURLY_BRACKET "\320"
+#define STR_TILDE "\241"
+
+#else /* EBCDIC_IGNORING_COMPILER */
+
+/* Otherwise, on a real EBCDIC compiler or an ASCII compiler, we can use simple
+string and character literals. */
+
+#ifdef EBCDIC
+#if 'a' != 0x81
+#error "EBCDIC character 'a' is not 0x81"
+#endif
+#else
+#if 'a' != 0x61
+#error "ASCII character 'a' is not 0x61"
+#endif
+#endif
#define CHAR_NUL '\0'
#define CHAR_HT '\t'
@@ -922,88 +1123,7 @@ a positive value. */
#define STR_RIGHT_CURLY_BRACKET "}"
#define STR_TILDE "~"
-#define STRING_ACCEPT0 "ACCEPT\0"
-#define STRING_COMMIT0 "COMMIT\0"
-#define STRING_F0 "F\0"
-#define STRING_FAIL0 "FAIL\0"
-#define STRING_MARK0 "MARK\0"
-#define STRING_PRUNE0 "PRUNE\0"
-#define STRING_SKIP0 "SKIP\0"
-#define STRING_THEN "THEN"
-
-#define STRING_atomic0 "atomic\0"
-#define STRING_pla0 "pla\0"
-#define STRING_plb0 "plb\0"
-#define STRING_napla0 "napla\0"
-#define STRING_naplb0 "naplb\0"
-#define STRING_nla0 "nla\0"
-#define STRING_nlb0 "nlb\0"
-#define STRING_scs0 "scs\0"
-#define STRING_sr0 "sr\0"
-#define STRING_asr0 "asr\0"
-#define STRING_positive_lookahead0 "positive_lookahead\0"
-#define STRING_positive_lookbehind0 "positive_lookbehind\0"
-#define STRING_non_atomic_positive_lookahead0 "non_atomic_positive_lookahead\0"
-#define STRING_non_atomic_positive_lookbehind0 "non_atomic_positive_lookbehind\0"
-#define STRING_negative_lookahead0 "negative_lookahead\0"
-#define STRING_negative_lookbehind0 "negative_lookbehind\0"
-#define STRING_script_run0 "script_run\0"
-#define STRING_atomic_script_run "atomic_script_run"
-#define STRING_scan_substring0 "scan_substring\0"
-
-#define STRING_alpha0 "alpha\0"
-#define STRING_lower0 "lower\0"
-#define STRING_upper0 "upper\0"
-#define STRING_alnum0 "alnum\0"
-#define STRING_ascii0 "ascii\0"
-#define STRING_blank0 "blank\0"
-#define STRING_cntrl0 "cntrl\0"
-#define STRING_digit0 "digit\0"
-#define STRING_graph0 "graph\0"
-#define STRING_print0 "print\0"
-#define STRING_punct0 "punct\0"
-#define STRING_space0 "space\0"
-#define STRING_word0 "word\0"
-#define STRING_xdigit "xdigit"
-
-#define STRING_DEFINE "DEFINE"
-#define STRING_VERSION "VERSION"
-#define STRING_WEIRD_STARTWORD "[:<:]]"
-#define STRING_WEIRD_ENDWORD "[:>:]]"
-
-#define STRING_CR_RIGHTPAR "CR)"
-#define STRING_LF_RIGHTPAR "LF)"
-#define STRING_CRLF_RIGHTPAR "CRLF)"
-#define STRING_ANY_RIGHTPAR "ANY)"
-#define STRING_ANYCRLF_RIGHTPAR "ANYCRLF)"
-#define STRING_NUL_RIGHTPAR "NUL)"
-#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
-#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
-#define STRING_UTF8_RIGHTPAR "UTF8)"
-#define STRING_UTF16_RIGHTPAR "UTF16)"
-#define STRING_UTF32_RIGHTPAR "UTF32)"
-#define STRING_UTF_RIGHTPAR "UTF)"
-#define STRING_UCP_RIGHTPAR "UCP)"
-#define STRING_NO_AUTO_POSSESS_RIGHTPAR "NO_AUTO_POSSESS)"
-#define STRING_NO_DOTSTAR_ANCHOR_RIGHTPAR "NO_DOTSTAR_ANCHOR)"
-#define STRING_NO_JIT_RIGHTPAR "NO_JIT)"
-#define STRING_NO_START_OPT_RIGHTPAR "NO_START_OPT)"
-#define STRING_NOTEMPTY_RIGHTPAR "NOTEMPTY)"
-#define STRING_NOTEMPTY_ATSTART_RIGHTPAR "NOTEMPTY_ATSTART)"
-#define STRING_CASELESS_RESTRICT_RIGHTPAR "CASELESS_RESTRICT)"
-#define STRING_TURKISH_CASING_RIGHTPAR "TURKISH_CASING)"
-#define STRING_LIMIT_HEAP_EQ "LIMIT_HEAP="
-#define STRING_LIMIT_MATCH_EQ "LIMIT_MATCH="
-#define STRING_LIMIT_DEPTH_EQ "LIMIT_DEPTH="
-#define STRING_LIMIT_RECURSION_EQ "LIMIT_RECURSION="
-#define STRING_MARK "MARK"
-
-#define STRING_bc "bc"
-#define STRING_bidiclass "bidiclass"
-#define STRING_sc "sc"
-#define STRING_script "script"
-#define STRING_scriptextensions "scriptextensions"
-#define STRING_scx "scx"
+#endif /* EBCDIC_WITH_ASCII_COMPILER */
#else /* SUPPORT_UNICODE */
@@ -1227,6 +1347,9 @@ only. */
#define STR_RIGHT_CURLY_BRACKET "\175"
#define STR_TILDE "\176"
+#endif /* SUPPORT_UNICODE */
+
+
#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0"
#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0"
#define STRING_F0 STR_F "\0"
@@ -1311,8 +1434,6 @@ only. */
#define STRING_scx STR_s STR_c STR_x
-#endif /* SUPPORT_UNICODE */
-
/* -------------------- End of character and string names -------------------*/
/* -------------------- Definitions for compiled patterns -------------------*/
@@ -1791,7 +1912,7 @@ pcre2_dfa_match.c that must be updated. */
/* This macro defines textual names for all the opcodes. These are used only
for debugging, and some of them are only partial names. The macro is referenced
-only in pcre2_printint.c, which fills out the full names in many cases (and in
+only in pcre2_printint_inc.h, which fills out the full names in many cases (and in
some cases doesn't actually use these names at all). */
#define OP_NAME_LIST \
@@ -2075,7 +2196,7 @@ tables are needed only when compiling the 8-bit library. */
#if PCRE2_CODE_UNIT_WIDTH == 8
extern const int PRIV(utf8_table1)[];
-extern const int PRIV(utf8_table1_size);
+extern const unsigned PRIV(utf8_table1_size);
extern const int PRIV(utf8_table2)[];
extern const int PRIV(utf8_table3)[];
extern const uint8_t PRIV(utf8_table4)[];
@@ -2110,6 +2231,8 @@ extern const uint8_t PRIV(utf8_table4)[];
#define _pcre2_utt PCRE2_SUFFIX(_pcre2_utt_)
#define _pcre2_utt_names PCRE2_SUFFIX(_pcre2_utt_names_)
#define _pcre2_utt_size PCRE2_SUFFIX(_pcre2_utt_size_)
+#define _pcre2_ebcdic_1047_to_ascii PCRE2_SUFFIX(_pcre2_ebcdic_1047_to_ascii_)
+#define _pcre2_ascii_to_ebcdic_1047 PCRE2_SUFFIX(_pcre2_ascii_to_ebcdic_1047_)
extern const uint8_t PRIV(OP_lengths)[];
extern const uint32_t PRIV(callout_end_delims)[];
@@ -2142,6 +2265,8 @@ extern const char *PRIV(unicode_version);
extern const ucp_type_table PRIV(utt)[];
extern const char PRIV(utt_names)[];
extern const size_t PRIV(utt_size);
+extern const uint8_t PRIV(ebcdic_1047_to_ascii)[];
+extern const uint8_t PRIV(ascii_to_ebcdic_1047)[];
/* Mode-dependent macros and hidden and private structures are defined in a
separate file so that pcre2test can include them at all supported widths. When
@@ -2165,6 +2290,7 @@ is available. */
#define _pcre2_auto_possessify PCRE2_SUFFIX(_pcre2_auto_possessify_)
#define _pcre2_check_escape PCRE2_SUFFIX(_pcre2_check_escape_)
+#define _pcre2_ckd_smul PCRE2_SUFFIX(_pcre2_ckd_smul_)
#define _pcre2_extuni PCRE2_SUFFIX(_pcre2_extuni_)
#define _pcre2_find_bracket PCRE2_SUFFIX(_pcre2_find_bracket_)
#define _pcre2_is_newline PCRE2_SUFFIX(_pcre2_is_newline_)
@@ -2191,6 +2317,7 @@ extern int _pcre2_auto_possessify(PCRE2_UCHAR *,
const compile_block *);
extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *,
int *, uint32_t, uint32_t, uint32_t, BOOL, compile_block *);
+extern BOOL _pcre2_ckd_smul(PCRE2_SIZE *, int, int);
extern PCRE2_SPTR _pcre2_extuni(uint32_t, PCRE2_SPTR, PCRE2_SPTR, PCRE2_SPTR,
BOOL, int *);
extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int);
@@ -2217,17 +2344,8 @@ extern BOOL _pcre2_xclass(uint32_t, PCRE2_SPTR, const uint8_t *, BOOL);
extern BOOL _pcre2_eclass(uint32_t, PCRE2_SPTR, PCRE2_SPTR,
const uint8_t *, BOOL);
-/* This function is needed only when memmove() is not available. */
-
-#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
-#define _pcre2_memmove PCRE2_SUFFIX(_pcre2_memmove)
-extern void * _pcre2_memmove(void *, const void *, size_t);
-#endif
-
#endif /* PCRE2_CODE_UNIT_WIDTH */
-extern BOOL PRIV(ckd_smul)(PCRE2_SIZE *, int, int);
-
#include "pcre2_util.h"
#endif /* PCRE2_INTERNAL_H_IDEMPOTENT_GUARD */
diff --git a/src/3rdparty/pcre2/src/pcre2_intmodedep.h b/src/3rdparty/pcre2/src/pcre2_intmodedep.h
index 6b858139f57..6cefb61d374 100644
--- a/src/3rdparty/pcre2/src/pcre2_intmodedep.h
+++ b/src/3rdparty/pcre2/src/pcre2_intmodedep.h
@@ -47,9 +47,16 @@ to have access to the hidden structures at all supported widths.
Some of the mode-dependent macros are required at different widths for
different parts of the pcre2test code (in particular, the included
-pcre2_printint.c file). We undefine them here so that they can be re-defined for
-multiple inclusions. Not all of these are used in pcre2test, but it's easier
-just to undefine them all. */
+pcre2_printint_inc.h file). We undefine them here so that they can be re-defined
+for multiple inclusions. Not all of these are used in pcre2test, but it's easier
+just to undefine them all.
+
+You can also include pcre2_intmodedep.h with PCRE2_CODE_UNIT_WIDTH defined to
+zero in order to simply clear the previous macros. */
+
+#ifndef PCRE2_CODE_UNIT_WIDTH
+#error PCRE2_CODE_UNIT_WIDTH must be defined
+#endif
#undef ACROSSCHAR
#undef BACKCHAR
@@ -81,9 +88,14 @@ just to undefine them all. */
#undef PUTINC
#undef TABLE_GET
+/*************************************************
+* MACROS *
+*************************************************/
+/* Macros may be undefined and re-defined if the same file handles multiple
+bit-widths. */
-/* -------------------------- MACROS ----------------------------- */
+#if PCRE2_CODE_UNIT_WIDTH != 0
/* PCRE keeps offsets in its compiled code as at least 16-bit quantities
(always stored in big-endian order in 8-bit mode) by default. These are used,
@@ -97,11 +109,23 @@ unit string is now handled by the macros that are defined here.
The macros are controlled by the value of LINK_SIZE. This defaults to 2, but
values of 3 or 4 are also supported. */
+#ifndef CONFIGURED_LINK_SIZE
+#if LINK_SIZE == 2
+#define CONFIGURED_LINK_SIZE 2
+#elif LINK_SIZE == 3
+#define CONFIGURED_LINK_SIZE 3
+#elif LINK_SIZE == 4
+#define CONFIGURED_LINK_SIZE 4
+#else
+#error LINK_SIZE must be 2, 3, or 4
+#endif
+#endif /* CONFIGURED_LINK_SIZE */
+
/* ------------------- 8-bit support ------------------ */
#if PCRE2_CODE_UNIT_WIDTH == 8
-#if LINK_SIZE == 2
+#if CONFIGURED_LINK_SIZE == 2
#define PUT(a,n,d) \
(a[n] = (PCRE2_UCHAR)((d) >> 8)), \
(a[(n)+1] = (PCRE2_UCHAR)((d) & 255))
@@ -109,7 +133,7 @@ values of 3 or 4 are also supported. */
(unsigned int)(((a)[n] << 8) | (a)[(n)+1])
#define MAX_PATTERN_SIZE (1 << 16)
-#elif LINK_SIZE == 3
+#elif CONFIGURED_LINK_SIZE == 3
#define PUT(a,n,d) \
(a[n] = (PCRE2_UCHAR)((d) >> 16)), \
(a[(n)+1] = (PCRE2_UCHAR)((d) >> 8)), \
@@ -118,7 +142,7 @@ values of 3 or 4 are also supported. */
(unsigned int)(((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
#define MAX_PATTERN_SIZE (1 << 24)
-#elif LINK_SIZE == 4
+#elif CONFIGURED_LINK_SIZE == 4
#define PUT(a,n,d) \
(a[n] = (PCRE2_UCHAR)((d) >> 24)), \
(a[(n)+1] = (PCRE2_UCHAR)((d) >> 16)), \
@@ -128,8 +152,6 @@ values of 3 or 4 are also supported. */
(unsigned int)(((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
-#else
-#error LINK_SIZE must be 2, 3, or 4
#endif
@@ -137,7 +159,7 @@ values of 3 or 4 are also supported. */
#elif PCRE2_CODE_UNIT_WIDTH == 16
-#if LINK_SIZE == 2
+#if CONFIGURED_LINK_SIZE == 2
#undef LINK_SIZE
#define LINK_SIZE 1
#define PUT(a,n,d) \
@@ -146,7 +168,7 @@ values of 3 or 4 are also supported. */
(a[n])
#define MAX_PATTERN_SIZE (1 << 16)
-#elif LINK_SIZE == 3 || LINK_SIZE == 4
+#elif CONFIGURED_LINK_SIZE == 3 || CONFIGURED_LINK_SIZE == 4
#undef LINK_SIZE
#define LINK_SIZE 2
#define PUT(a,n,d) \
@@ -156,8 +178,6 @@ values of 3 or 4 are also supported. */
(unsigned int)(((a)[n] << 16) | (a)[(n)+1])
#define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */
-#else
-#error LINK_SIZE must be 2, 3, or 4
#endif
@@ -194,7 +214,7 @@ arithmetic results in a signed value. Hence the cast. */
#define GET2(a,n) (unsigned int)(((a)[n] << 8) | (a)[(n)+1])
#define PUT2(a,n,d) a[n] = (d) >> 8, a[(n)+1] = (d) & 255
-#else /* Code units are 16 or 32 bits */
+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
#define IMM2_SIZE 1
#define GET2(a,n) a[n]
#define PUT2(a,n,d) a[n] = d
@@ -219,7 +239,7 @@ check is needed before accessing these tables. */
#define CHMAX_255(c) TRUE
#endif /* SUPPORT_UNICODE */
-#else /* Code units are 16 or 32 bits */
+#elif PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
#define CHMAX_255(c) ((c) <= 255u)
#define MAX_255(c) ((c) <= 255u)
#define MAX_MARK ((1u << 16) - 1)
@@ -285,7 +305,7 @@ UTF support is omitted, we don't even define them. */
#define HAS_EXTRALEN(c) HASUTF8EXTRALEN(c)
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+/* Returns with the additional number of characters if HAS_EXTRALEN(c) is TRUE.
Otherwise it has an undefined behaviour. */
#define GET_EXTRALEN(c) (PRIV(utf8_table4)[(c) & 0x3fu])
@@ -371,7 +391,7 @@ because almost all calls are already within a block of UTF-8 only code. */
#define HAS_EXTRALEN(c) (((c) & 0xfc00u) == 0xd800u)
-/* Returns with the additional number of characters if IS_MULTICHAR(c) is TRUE.
+/* Returns with the additional number of characters if HAS_EXTRALEN(c) is TRUE.
Otherwise it has an undefined behaviour. */
#define GET_EXTRALEN(c) 1
@@ -466,7 +486,7 @@ code. */
/* ------------------- 32-bit support ------------------ */
-#else
+#elif PCRE2_CODE_UNIT_WIDTH == 32
/* These are trivial for the 32-bit library, since all UTF-32 characters fit
into one PCRE2_UCHAR unit. */
@@ -547,6 +567,32 @@ These are all no-ops since all UTF-32 characters fit into one PCRE2_UCHAR. */
#define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE
#define PUT2INC(a,n,d) PUT2(a,n,d), a += IMM2_SIZE
+#endif /* PCRE2_CODE_UNIT_WIDTH != 0 */
+
+
+
+/*************************************************
+* STRUCTURES *
+*************************************************/
+
+/* We need a more complex include guard than usual, because the file can be
+included once for each bit-width to define the various structures. */
+
+#if PCRE2_CODE_UNIT_WIDTH == 8 && !defined PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_8
+#define PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_8
+#define PCRE2_INTMODEDEP_CAN_DEFINE
+#endif
+#if PCRE2_CODE_UNIT_WIDTH == 16 && !defined PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_16
+#define PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_16
+#define PCRE2_INTMODEDEP_CAN_DEFINE
+#endif
+#if PCRE2_CODE_UNIT_WIDTH == 32 && !defined PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_32
+#define PCRE2_INTMODEDEP_IDEMPOTENT_GUARD_32
+#define PCRE2_INTMODEDEP_CAN_DEFINE
+#endif
+
+#ifdef PCRE2_INTMODEDEP_CAN_DEFINE
+#undef PCRE2_INTMODEDEP_CAN_DEFINE
/* ----------------------- HIDDEN STRUCTURES ----------------------------- */
@@ -624,7 +670,7 @@ have 16-bit arguments in 8-bit and 16-bit modes, so we need no more than a
#define CODE_BLOCKSIZE_TYPE PCRE2_SIZE
#undef LOOKBEHIND_MAX
-#define LOOKBEHIND_MAX UINT16_MAX
+#define LOOKBEHIND_MAX ((int)UINT16_MAX)
typedef struct pcre2_real_code {
pcre2_memctl memctl; /* Memory control fields */
@@ -672,12 +718,14 @@ typedef struct pcre2_real_match_data {
struct heapframe *heapframes; /* Backtracking frames heap memory */
PCRE2_SIZE heapframes_size; /* Malloc-ed size */
PCRE2_SIZE subject_length; /* Subject length */
+ PCRE2_SIZE start_offset; /* Offset to start of search */
PCRE2_SIZE leftchar; /* Offset to leftmost code unit */
PCRE2_SIZE rightchar; /* Offset to rightmost code unit */
PCRE2_SIZE startchar; /* Offset to starting code unit */
uint8_t matchedby; /* Type of match (normal, JIT, DFA) */
uint8_t flags; /* Various flags */
uint16_t oveccount; /* Number of pairs */
+ uint32_t options; /* Options passed in to the match call */
int rc; /* The return code from the match */
PCRE2_SIZE ovector[131072]; /* Must be last in the structure */
} pcre2_real_match_data;
@@ -718,20 +766,31 @@ typedef struct branch_chain {
} branch_chain;
/* Structure for building a list of named groups during the first pass of
-compiling. */
+compiling. When a duplicate name is stored in the list, its name is set to
+the name of the first entry with the same name, and its length is set to 0. */
typedef struct named_group {
PCRE2_SPTR name; /* Points to the name in the pattern */
uint32_t number; /* Group number */
uint16_t length; /* Length of the name */
- uint16_t isdup; /* TRUE if a duplicate */
+ uint16_t hash_dup; /* A concatenation of a 15 bit hash code and
+ a singe bit which represents duplication */
} named_group;
+/* Structure for storing compile time data. */
+
+typedef struct compile_data {
+ struct compile_data *next; /* Next compile data */
+#ifdef PCRE2_DEBUG
+ uint8_t type; /* Debug only type of the data */
+#endif
+} compile_data;
+
/* Structure for caching sorted ranges. This improves the performance
of translating META code to byte code. */
typedef struct class_ranges {
- struct class_ranges *next; /* Next class ranges */
+ compile_data header; /* Common header */
size_t char_lists_size; /* Total size of encoded char lists */
size_t char_lists_start; /* Start offset of encoded char lists */
uint16_t range_list_size; /* Size of ranges array */
@@ -739,6 +798,14 @@ typedef struct class_ranges {
/* Followed by the list of ranges (start/end pairs) */
} class_ranges;
+/* Structure for sorted recurse arguments. */
+
+typedef struct recurse_arguments {
+ compile_data header; /* Common header */
+ size_t size; /* Total size */
+ size_t skip_size; /* Space consumed by arguments */
+} recurse_arguments;
+
typedef union class_bits_storage {
uint8_t classbits[32];
uint32_t classwords[8];
@@ -789,9 +856,9 @@ typedef struct compile_block {
BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */
BOOL had_recurse; /* Had a pattern recursion or subroutine call */
BOOL dupnames; /* Duplicate names exist */
+ compile_data *first_data; /* First item in the compile data list */
+ compile_data *last_data; /* Last item in the compile data list */
#ifdef SUPPORT_WIDE_CHARS
- class_ranges *cranges; /* First class range. */
- class_ranges *next_cranges; /* Next class range. */
size_t char_lists_size; /* Current size of character lists */
#endif
} compile_block;
@@ -902,7 +969,9 @@ typedef struct match_block {
uint32_t match_call_count; /* Number of times a new frame is created */
BOOL hitend; /* Hit the end of the subject at some point */
BOOL hasthen; /* Pattern contains (*THEN) */
+ BOOL hasbsk; /* Pattern contains \K */
BOOL allowemptypartial; /* Allow empty hard partial */
+ BOOL allowlookaroundbsk; /* Allow \K within lookarounds */
const uint8_t *lcc; /* Points to lower casing table */
const uint8_t *fcc; /* Points to case-flipping table */
const uint8_t *ctypes; /* Points to table of type maps */
@@ -970,4 +1039,6 @@ typedef struct dfa_match_block {
#endif /* PCRE2_PCRE2TEST */
+#endif /* PCRE2_INTMODEDEP_CAN_DEFINE */
+
/* End of pcre2_intmodedep.h */
diff --git a/src/3rdparty/pcre2/src/pcre2_jit_char_inc.h b/src/3rdparty/pcre2/src/pcre2_jit_char_inc.h
index 69fe938fc5b..0976742bb3b 100644
--- a/src/3rdparty/pcre2/src/pcre2_jit_char_inc.h
+++ b/src/3rdparty/pcre2/src/pcre2_jit_char_inc.h
@@ -519,6 +519,8 @@ BOOL has_cmov, last_range_set;
sljit_u32 category_list = 0;
sljit_u32 items;
int typereg = TMP1;
+#else
+(void)c; /* Avoid compiler warning. */
#endif /* SUPPORT_UNICODE */
SLJIT_ASSERT(common->locals_size >= SSIZE_OF(sw));
@@ -568,7 +570,7 @@ while (*cc == XCL_PROP || *cc == XCL_NOTPROP)
break;
}
compares++;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case PT_SC:
status |= XCLASS_HAS_SCRIPT;
@@ -696,13 +698,11 @@ if (status & XCLASS_NEEDS_UCD)
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
- OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
- OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+ sljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP1, 0, TMP1, 0, TMP2, 0, UCD_BLOCK_SHIFT);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
- OP2(SLJIT_SHL, TMP1, 0, TMP2, 0, SLJIT_IMM, 3);
+ sljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP2, 0, TMP2, 0, TMP2, 0, 1);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
- OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0);
ccbegin = cc;
@@ -768,7 +768,7 @@ if (status & XCLASS_NEEDS_UCD)
case PT_SCX:
if (cc[-1] == XCL_NOTPROP)
break;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case PT_SC:
compares--;
@@ -1104,7 +1104,7 @@ if (ranges.range_count >= 6)
depth = 0;
first_item = 0;
-last_item = ranges.range_count - 2;
+last_item = (sljit_u32)(ranges.range_count - 2);
has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV) != 0;
while (TRUE)
@@ -1486,7 +1486,7 @@ static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc)
{
PCRE2_SPTR start_subject = args->begin;
PCRE2_SPTR end_subject = args->end;
-int lgb, rgb, ricount;
+int lgb = 0, rgb, ricount;
PCRE2_SPTR prevcc, endcc, bptr;
BOOL first = TRUE;
BOOL was_ep_ZWJ = FALSE;
@@ -1569,7 +1569,7 @@ static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SP
{
PCRE2_SPTR start_subject = args->begin;
PCRE2_SPTR end_subject = args->end;
-int lgb, rgb, ricount;
+int lgb = 0, rgb, ricount;
PCRE2_SPTR prevcc, endcc, bptr;
BOOL first = TRUE;
BOOL was_ep_ZWJ = FALSE;
@@ -1964,9 +1964,9 @@ switch(type)
detect_partial_match(common, backtracks);
if (type == OP_NOT_HSPACE)
- read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR);
+ read_char(common, 0x1, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR);
else
- read_char(common, 0x9, 0x3000, NULL, 0);
+ read_char(common, 0x1, 0x3000, NULL, 0);
add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
sljit_set_current_flags(compiler, SLJIT_SET_Z);
@@ -1979,9 +1979,9 @@ switch(type)
detect_partial_match(common, backtracks);
if (type == OP_NOT_VSPACE)
- read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR);
+ read_char(common, 0x1, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR);
else
- read_char(common, 0xa, 0x2029, NULL, 0);
+ read_char(common, 0x1, 0x2029, NULL, 0);
add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
sljit_set_current_flags(compiler, SLJIT_SET_Z);
diff --git a/src/3rdparty/pcre2/src/pcre2_jit_compile.c b/src/3rdparty/pcre2/src/pcre2_jit_compile.c
index 175eb68535c..3ab4592c3ad 100644
--- a/src/3rdparty/pcre2/src/pcre2_jit_compile.c
+++ b/src/3rdparty/pcre2/src/pcre2_jit_compile.c
@@ -39,10 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
#include <sanitizer/msan_interface.h>
@@ -339,6 +335,10 @@ typedef struct recurse_entry {
jump_list *backtrack_calls;
/* Points to the starting opcode. */
sljit_sw start;
+ /* Start of caller arguments. */
+ PCRE2_SPTR arg_start;
+ /* Size of caller arguments in bytes. */
+ sljit_uw arg_size;
} recurse_entry;
typedef struct recurse_backtrack {
@@ -398,8 +398,10 @@ typedef struct compiler_common {
sljit_s32 *private_data_ptrs;
/* Chain list of read-only data ptrs. */
void *read_only_data_head;
- /* Tells whether the capturing bracket is optimized. */
- sljit_u8 *optimized_cbracket;
+ /* Bitset which tells which capture brackets can be optimized. */
+ sljit_u8 *optimized_cbrackets;
+ /* Bitset for tracking capture bracket status. */
+ sljit_u8 *cbracket_bitset;
/* Tells whether the starting offset is a target of then. */
sljit_u8 *then_offsets;
/* Current position where a THEN must jump. */
@@ -443,6 +445,8 @@ typedef struct compiler_common {
/* Locals used by fast fail optimization. */
sljit_s32 early_fail_start_ptr;
sljit_s32 early_fail_end_ptr;
+ /* Byte length of optimized_cbrackets and cbracket_bitset. */
+ sljit_u32 cbracket_bitset_length;
/* Variables used by recursive call generator. */
sljit_s32 recurse_bitset_size;
uint8_t *recurse_bitset;
@@ -1143,6 +1147,18 @@ if (*cc >= OP_CRSTAR && *cc <= OP_CRPOSRANGE)
return (current_locals_size >= locals_size) ? current_locals_size : locals_size;
}
+static SLJIT_INLINE BOOL is_optimized_cbracket(compiler_common *common, sljit_s32 capture_index)
+{
+sljit_u8 bit = (sljit_u8)(1 << (capture_index & 0x7));
+return (common->optimized_cbrackets[capture_index >> 3] & bit) != 0;
+}
+
+static SLJIT_INLINE void clear_optimized_cbracket(compiler_common *common, sljit_s32 capture_index)
+{
+sljit_u8 mask = (sljit_u8)~(1 << (capture_index & 0x7));
+common->optimized_cbrackets[capture_index >> 3] &= mask;
+}
+
static BOOL check_opcode_types(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend)
{
int count;
@@ -1193,7 +1209,7 @@ while (cc < ccend)
case OP_REFI:
case OP_REF:
locals_size = ref_update_local_size(common, cc, locals_size);
- common->optimized_cbracket[GET2(cc, 1)] = 0;
+ clear_optimized_cbracket(common, GET2(cc, 1));
cc += PRIV(OP_lengths)[*cc];
break;
@@ -1208,7 +1224,7 @@ while (cc < ccend)
case OP_CBRAPOS:
case OP_SCBRAPOS:
- common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
+ clear_optimized_cbracket(common, GET2(cc, 1 + LINK_SIZE));
cc += 1 + LINK_SIZE + IMM2_SIZE;
break;
@@ -1222,20 +1238,20 @@ while (cc < ccend)
break;
case OP_CREF:
- common->optimized_cbracket[GET2(cc, 1)] = 0;
+ clear_optimized_cbracket(common, GET2(cc, 1));
cc += 1 + IMM2_SIZE;
break;
case OP_DNREFI:
case OP_DNREF:
locals_size = ref_update_local_size(common, cc, locals_size);
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_DNCREF:
count = GET2(cc, 1 + IMM2_SIZE);
slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
while (count-- > 0)
{
- common->optimized_cbracket[GET2(slot, 0)] = 0;
+ clear_optimized_cbracket(common, GET2(slot, 0));
slot += common->name_entry_size;
}
cc += PRIV(OP_lengths)[*cc];
@@ -1245,6 +1261,11 @@ while (cc < ccend)
/* Set its value only once. */
set_recursive_head = TRUE;
cc += 1 + LINK_SIZE;
+ while (*cc == OP_CREF)
+ {
+ clear_optimized_cbracket(common, GET2(cc, 1));
+ cc += 1 + IMM2_SIZE;
+ }
break;
case OP_CALLOUT:
@@ -1263,7 +1284,7 @@ while (cc < ccend)
case OP_THEN_ARG:
common->has_then = TRUE;
common->control_head_ptr = 1;
- /* Fall through. */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_COMMIT_ARG:
case OP_PRUNE_ARG:
@@ -1313,7 +1334,7 @@ while (cc < ccend)
if (common->utf && locals_size <= 3 * SSIZE_OF(sw))
locals_size = 3 * SSIZE_OF(sw);
#endif
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
default:
cc = next_opcode(common, cc);
if (cc == NULL)
@@ -1379,7 +1400,7 @@ int result = 0;
int count, prev_count;
SLJIT_ASSERT(*cc == OP_ONCE || *cc == OP_BRA || *cc == OP_CBRA);
-SLJIT_ASSERT(*cc != OP_CBRA || common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] != 0);
+SLJIT_ASSERT(*cc != OP_CBRA || is_optimized_cbracket(common, GET2(cc, 1 + LINK_SIZE)));
SLJIT_ASSERT(start < EARLY_FAIL_ENHANCE_MAX);
next_alt = cc + GET(cc, 1);
@@ -1462,7 +1483,7 @@ do
case OP_TYPEMINPLUS:
if (count == 2)
count = 3;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_TYPESTAR:
case OP_TYPEPLUS:
@@ -1491,7 +1512,7 @@ do
case OP_TYPEMINUPTO:
case OP_TYPEPOSUPTO:
cc += IMM2_SIZE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_TYPEQUERY:
case OP_TYPEMINQUERY:
@@ -1512,7 +1533,7 @@ do
case OP_NOTMINPLUSI:
if (count == 2)
count = 3;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_STAR:
case OP_PLUS:
@@ -1565,7 +1586,7 @@ do
case OP_NOTEXACTI:
case OP_NOTPOSUPTOI:
cc += IMM2_SIZE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_QUERY:
case OP_MINQUERY:
@@ -1605,7 +1626,7 @@ do
case OP_CRMINPLUS:
if (count == 2)
count = 3;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CRSTAR:
case OP_CRPLUS:
@@ -1627,7 +1648,7 @@ do
}
cc += 2 * IMM2_SIZE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CRQUERY:
case OP_CRMINQUERY:
case OP_CRPOSQUERY:
@@ -1657,7 +1678,7 @@ do
count = 3;
end = bracketend(cc);
- if (end[-1 - LINK_SIZE] != OP_KET || (*cc == OP_CBRA && common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0))
+ if (end[-1 - LINK_SIZE] != OP_KET || (*cc == OP_CBRA && !is_optimized_cbracket(common, GET2(cc, 1 + LINK_SIZE))))
break;
prev_count = detect_early_fail(common, cc, private_data_start, depth + 1, prev_count);
@@ -1838,7 +1859,8 @@ if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
if (i == max)
{
- common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
+ /* Patterns must fit into an int32 even for link-size=4. */
+ common->private_data_ptrs[max_end - common->start - LINK_SIZE] = (sljit_s32)(next_end - max_end);
common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
/* +2 the original and the last. */
common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
@@ -1853,7 +1875,7 @@ if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
if (min >= 3)
{
- common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
+ common->private_data_ptrs[end - common->start - LINK_SIZE] = (sljit_s32)(max_end - end);
common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
return TRUE;
@@ -2118,11 +2140,22 @@ while (cc < ccend)
*private_data_start = private_data_ptr;
}
+static SLJIT_INLINE BOOL is_cbracket_processed(compiler_common *common, sljit_s32 capture_index)
+{
+sljit_u8 bit = (sljit_u8)(1 << (capture_index & 0x7));
+sljit_u8 *ptr = common->cbracket_bitset + (capture_index >> 3);
+sljit_u8 value = *ptr;
+
+*ptr |= bit;
+return (value & bit) != 0;
+}
+
/* Returns with a frame_types (always < 0) if no need for frame. */
static int get_framesize(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, BOOL recursive, BOOL *needs_control_head)
{
int length = 0;
int possessive = 0;
+int offset;
BOOL stack_restore = FALSE;
BOOL setsom_found = recursive;
BOOL setmark_found = recursive;
@@ -2136,6 +2169,8 @@ SLJIT_ASSERT(common->control_head_ptr != 0);
*needs_control_head = FALSE;
#endif
+memset(common->cbracket_bitset, 0, common->cbracket_bitset_length);
+
if (ccend == NULL)
{
ccend = bracketend(cc) - (1 + LINK_SIZE);
@@ -2196,7 +2231,15 @@ while (cc < ccend)
length += 2;
capture_last_found = TRUE;
}
+
cc += 1 + LINK_SIZE;
+ while (*cc == OP_CREF)
+ {
+ offset = GET2(cc, 1);
+ if (!is_cbracket_processed(common, offset))
+ length += 3;
+ cc += 1 + IMM2_SIZE;
+ }
break;
case OP_CBRA:
@@ -2209,7 +2252,10 @@ while (cc < ccend)
length += 2;
capture_last_found = TRUE;
}
- length += 3;
+
+ offset = GET2(cc, 1 + LINK_SIZE);
+ if (!is_cbracket_processed(common, offset))
+ length += 3;
cc += 1 + LINK_SIZE + IMM2_SIZE;
break;
@@ -2222,7 +2268,7 @@ while (cc < ccend)
default:
stack_restore = TRUE;
- /* Fall through. */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_NOT_WORD_BOUNDARY:
case OP_WORD_BOUNDARY:
@@ -2322,6 +2368,8 @@ int offset;
SLJIT_UNUSED_ARG(stacktop);
SLJIT_ASSERT(stackpos >= stacktop + 2);
+memset(common->cbracket_bitset, 0, common->cbracket_bitset_length);
+
stackpos = STACK(stackpos);
if (ccend == NULL)
{
@@ -2395,6 +2443,23 @@ while (cc < ccend)
capture_last_found = TRUE;
}
cc += 1 + LINK_SIZE;
+ while (*cc == OP_CREF)
+ {
+ offset = GET2(cc, 1);
+ if (!is_cbracket_processed(common, offset))
+ {
+ offset <<= 1;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
+ stackpos -= SSIZE_OF(sw);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos -= SSIZE_OF(sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
+ stackpos -= SSIZE_OF(sw);
+ }
+ cc += 1 + IMM2_SIZE;
+ }
break;
case OP_CBRA:
@@ -2410,15 +2475,20 @@ while (cc < ccend)
stackpos -= SSIZE_OF(sw);
capture_last_found = TRUE;
}
- offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
- OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
- stackpos -= SSIZE_OF(sw);
- OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
- stackpos -= SSIZE_OF(sw);
+
+ offset = GET2(cc, 1 + LINK_SIZE);
+ if (!is_cbracket_processed(common, offset))
+ {
+ offset <<= 1;
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
+ stackpos -= SSIZE_OF(sw);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
+ stackpos -= SSIZE_OF(sw);
+ OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
+ stackpos -= SSIZE_OF(sw);
+ }
cc += 1 + LINK_SIZE + IMM2_SIZE;
break;
@@ -2438,7 +2508,7 @@ SLJIT_ASSERT(stackpos == STACK(stacktop));
typedef struct delayed_mem_copy_status {
struct sljit_compiler *compiler;
int store_bases[RECURSE_TMP_REG_COUNT];
- int store_offsets[RECURSE_TMP_REG_COUNT];
+ sljit_s32 store_offsets[RECURSE_TMP_REG_COUNT];
int tmp_regs[RECURSE_TMP_REG_COUNT];
int saved_tmp_regs[RECURSE_TMP_REG_COUNT];
int next_tmp_reg;
@@ -2460,7 +2530,7 @@ status->compiler = common->compiler;
}
static void delayed_mem_copy_move(delayed_mem_copy_status *status, int load_base, sljit_sw load_offset,
- int store_base, sljit_sw store_offset)
+ int store_base, sljit_s32 store_offset)
{
struct sljit_compiler *compiler = status->compiler;
int next_tmp_reg = status->next_tmp_reg;
@@ -2537,17 +2607,31 @@ enum get_recurse_flags {
recurse_flag_setsom_found = (1 << 2),
recurse_flag_setmark_found = (1 << 3),
recurse_flag_control_head_found = (1 << 4),
+ recurse_flag_recurse_arg = (1 << 5),
};
static int get_recurse_data_length(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR ccend, uint32_t *result_flags)
{
int length = 1;
int size, offset;
-PCRE2_SPTR alternative;
+PCRE2_SPTR alternative, cref;
uint32_t recurse_flags = 0;
memset(common->recurse_bitset, 0, common->recurse_bitset_size);
+if (common->currententry->arg_size > 0)
+ {
+ cref = common->currententry->arg_start;
+
+ do
+ {
+ offset = GET2(cref, 1);
+ recurse_check_bit(common, OVECTOR(offset << 1));
+ cref += 1 + IMM2_SIZE;
+ }
+ while (*cref == OP_CREF);
+ }
+
#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
SLJIT_ASSERT(common->control_head_ptr != 0);
recurse_flags |= recurse_flag_control_head_found;
@@ -2573,6 +2657,8 @@ while (cc < ccend)
if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
length++;
cc += 1 + LINK_SIZE;
+ if (*cc == OP_CREF)
+ recurse_flags |= recurse_flag_recurse_arg;
break;
case OP_KET:
@@ -2605,6 +2691,22 @@ while (cc < ccend)
cc += 1 + LINK_SIZE;
break;
+ case OP_CREF:
+ if ((recurse_flags & recurse_flag_recurse_arg) != 0)
+ {
+ offset = GET2(cc, 1);
+ if (recurse_check_bit(common, OVECTOR(offset << 1)))
+ {
+ SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
+ length += 2;
+ }
+
+ if (cc[1 + IMM2_SIZE] != OP_CREF)
+ recurse_flags &= ~(uint32_t)recurse_flag_recurse_arg;
+ }
+ cc += 1 + IMM2_SIZE;
+ break;
+
case OP_ASSERT_SCS:
SLJIT_ASSERT(PRIVATE_DATA(cc) != 0);
if (recurse_check_bit(common, PRIVATE_DATA(cc)))
@@ -2620,7 +2722,7 @@ while (cc < ccend)
SLJIT_ASSERT(recurse_check_bit(common, OVECTOR((offset << 1) + 1)));
length += 2;
}
- if (common->optimized_cbracket[offset] == 0 && recurse_check_bit(common, OVECTOR_PRIV(offset)))
+ if (!is_optimized_cbracket(common, offset) && recurse_check_bit(common, OVECTOR_PRIV(offset)))
length++;
if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
length++;
@@ -2803,7 +2905,7 @@ static void copy_recurse_data(compiler_common *common, PCRE2_SPTR cc, PCRE2_SPTR
int type, int stackptr, int stacktop, uint32_t recurse_flags)
{
delayed_mem_copy_status status;
-PCRE2_SPTR alternative;
+PCRE2_SPTR alternative, cref;
sljit_sw private_srcw[2];
sljit_sw shared_srcw[3];
sljit_sw kept_shared_srcw[2];
@@ -2812,6 +2914,19 @@ int from_sp, base_reg, offset, i;
memset(common->recurse_bitset, 0, common->recurse_bitset_size);
+if (common->currententry->arg_size > 0)
+ {
+ cref = common->currententry->arg_start;
+
+ do
+ {
+ offset = GET2(cref, 1);
+ recurse_check_bit(common, OVECTOR(offset << 1));
+ cref += 1 + IMM2_SIZE;
+ }
+ while (*cref == OP_CREF);
+ }
+
#if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
SLJIT_ASSERT(common->control_head_ptr != 0);
recurse_check_bit(common, common->control_head_ptr);
@@ -2924,12 +3039,16 @@ while (cc < ccend)
kept_shared_count++;
}
}
+
if (common->capture_last_ptr != 0 && recurse_check_bit(common, common->capture_last_ptr))
{
shared_srcw[0] = common->capture_last_ptr;
shared_count = 1;
}
+
cc += 1 + LINK_SIZE;
+ if (*cc == OP_CREF)
+ recurse_flags |= recurse_flag_recurse_arg;
break;
case OP_KET:
@@ -2962,6 +3081,24 @@ while (cc < ccend)
cc += 1 + LINK_SIZE;
break;
+ case OP_CREF:
+ if ((recurse_flags & recurse_flag_recurse_arg) != 0)
+ {
+ offset = GET2(cc, 1);
+ shared_srcw[0] = OVECTOR(offset << 1);
+ if (recurse_check_bit(common, shared_srcw[0]))
+ {
+ shared_srcw[1] = shared_srcw[0] + sizeof(sljit_sw);
+ SLJIT_ASSERT(recurse_check_bit(common, shared_srcw[1]));
+ shared_count = 2;
+ }
+
+ if (cc[1 + IMM2_SIZE] != OP_CREF)
+ recurse_flags &= ~(uint32_t)recurse_flag_recurse_arg;
+ }
+ cc += 1 + IMM2_SIZE;
+ break;
+
case OP_ASSERT_SCS:
private_srcw[0] = PRIVATE_DATA(cc);
private_srcw[1] = private_srcw[0] + sizeof(sljit_sw);
@@ -2987,7 +3124,7 @@ while (cc < ccend)
shared_count++;
}
- if (common->optimized_cbracket[offset] == 0)
+ if (!is_optimized_cbracket(common, offset))
{
private_srcw[0] = OVECTOR_PRIV(offset);
if (recurse_check_bit(common, private_srcw[0]))
@@ -3184,7 +3321,7 @@ while (cc < ccend)
SLJIT_ASSERT(private_srcw[i] != 0);
if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, private_srcw[i]);
+ delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, (sljit_s32)private_srcw[i]);
if (from_sp || type == recurse_swap_global)
delayed_mem_copy_move(&status, SLJIT_SP, private_srcw[i], base_reg, stackptr);
@@ -3204,7 +3341,7 @@ while (cc < ccend)
SLJIT_ASSERT(shared_srcw[i] != 0);
if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, shared_srcw[i]);
+ delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, (sljit_s32)shared_srcw[i]);
if (from_sp || type == recurse_swap_global)
delayed_mem_copy_move(&status, SLJIT_SP, shared_srcw[i], base_reg, stackptr);
@@ -3224,7 +3361,7 @@ while (cc < ccend)
SLJIT_ASSERT(kept_shared_srcw[i] != 0);
if (!from_sp)
- delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, kept_shared_srcw[i]);
+ delayed_mem_copy_move(&status, base_reg, stackptr, SLJIT_SP, (sljit_s32)kept_shared_srcw[i]);
if (from_sp || type == recurse_swap_global)
delayed_mem_copy_move(&status, SLJIT_SP, kept_shared_srcw[i], base_reg, stackptr);
@@ -3380,7 +3517,7 @@ OP2(SLJIT_SUB | SLJIT_SET_Z, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
add_jump(compiler, &common->calllimit, JUMP(SLJIT_ZERO));
}
-static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
+static SLJIT_INLINE void allocate_stack(compiler_common *common, sljit_s32 size)
{
/* May destroy all locals and registers except TMP2. */
DEFINE_COMPILER;
@@ -3401,7 +3538,7 @@ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, TMP1, 0);
add_stub(common, CMP(SLJIT_LESS, STACK_TOP, 0, STACK_LIMIT, 0));
}
-static SLJIT_INLINE void free_stack(compiler_common *common, int size)
+static SLJIT_INLINE void free_stack(compiler_common *common, sljit_s32 size)
{
DEFINE_COMPILER;
@@ -3827,9 +3964,12 @@ oc = TABLE_GET(c, common->fcc, c);
SLJIT_ASSERT(c != oc);
bit = c ^ oc;
+
+#ifndef EBCDIC
/* Optimized for English alphabet. */
if (c <= 127 && bit == 0x20)
return (0 << 8) | 0x20;
+#endif
/* Since c != oc, they must have at least 1 bit difference. */
if (!is_powerof2(bit))
@@ -5433,8 +5573,7 @@ OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+sljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP1, 0, TMP1, 0, TMP2, 0, UCD_BLOCK_SHIFT);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
@@ -5473,16 +5612,14 @@ OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
+sljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP1, 0, TMP1, 0, TMP2, 0, UCD_BLOCK_SHIFT);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
-/* TMP2 is multiplied by 12. Same as (TMP2 << 2) + ((TMP2 << 2) << 1). */
+/* TMP2 is multiplied by 12. Same as (TMP2 + (TMP2 << 1)) << 2. */
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
-OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
-OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
-OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 1);
+sljit_emit_op2_shift(compiler, SLJIT_ADD | SLJIT_SHL_IMM | SLJIT_SRC2_UNDEFINED, TMP2, 0, TMP2, 0, TMP2, 0, 1);
+OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 2);
OP_SRC(SLJIT_FAST_RETURN, RETURN_ADDR, 0);
}
@@ -5807,7 +5944,7 @@ while (TRUE)
{
case OP_CHARI:
caseless = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CHAR:
last = FALSE;
cc++;
@@ -5844,7 +5981,7 @@ while (TRUE)
case OP_MINPLUSI:
case OP_POSPLUSI:
caseless = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_PLUS:
case OP_MINPLUS:
case OP_POSPLUS:
@@ -5853,7 +5990,7 @@ while (TRUE)
case OP_EXACTI:
caseless = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_EXACT:
repeat = GET2(cc, 1);
last = FALSE;
@@ -5864,7 +6001,7 @@ while (TRUE)
case OP_MINQUERYI:
case OP_POSQUERYI:
caseless = TRUE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_QUERY:
case OP_MINQUERY:
case OP_POSQUERY:
@@ -5996,7 +6133,7 @@ while (TRUE)
case OP_NOT:
case OP_NOTI:
cc++;
- /* Fall through. */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_NOT_DIGIT:
case OP_NOT_WHITESPACE:
case OP_NOT_WORDCHAR:
@@ -6079,7 +6216,7 @@ while (TRUE)
case OP_CRMINQUERY:
case OP_CRPOSQUERY:
last = FALSE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CRSTAR:
case OP_CRMINSTAR:
case OP_CRPOSSTAR:
@@ -6751,7 +6888,7 @@ if (JIT_HAS_FAST_FORWARD_CHAR_SIMD && (common->nltype == NLTYPE_FIXED || common-
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
quit = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
}
- else
+ else
{
fast_forward_char_simd(common, common->newline, common->newline, 0);
@@ -7435,10 +7572,22 @@ DEFINE_COMPILER;
sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+#ifdef EBCDIC
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_LF);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_VT);
+OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_FF);
+OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_CR);
+OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL);
+#else
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, CHAR_LF);
+OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR - CHAR_LF);
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL - CHAR_LF);
+#endif
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
#if PCRE2_CODE_UNIT_WIDTH == 8
if (common->utf)
@@ -7446,7 +7595,7 @@ if (common->utf)
#endif
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+ OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - CHAR_LF);
#if PCRE2_CODE_UNIT_WIDTH == 8
}
#endif
@@ -7462,11 +7611,11 @@ DEFINE_COMPILER;
sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x09);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_HT);
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x20);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_SPACE);
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0xa0);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NBSP);
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
#if PCRE2_CODE_UNIT_WIDTH == 8
if (common->utf)
@@ -7478,7 +7627,7 @@ if (common->utf)
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x180e);
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
- OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
+ OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x200a - 0x2000);
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL);
OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
@@ -7501,10 +7650,22 @@ DEFINE_COMPILER;
sljit_emit_op_dst(compiler, SLJIT_FAST_ENTER, RETURN_ADDR, 0);
-OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
-OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
+#ifdef EBCDIC
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_LF);
+OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_VT);
+OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_FF);
+OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_CR);
+OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL);
+#else
+OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, CHAR_LF);
+OP2U(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR - CHAR_LF);
OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL);
-OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
+OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, CHAR_NEL - CHAR_LF);
+#endif
#if defined SUPPORT_UNICODE || PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32
#if PCRE2_CODE_UNIT_WIDTH == 8
if (common->utf)
@@ -7512,7 +7673,7 @@ if (common->utf)
#endif
OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_EQUAL);
OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
- OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
+ OP2U(SLJIT_SUB | SLJIT_SET_Z, TMP1, 0, SLJIT_IMM, 0x2029 - CHAR_LF);
#if PCRE2_CODE_UNIT_WIDTH == 8
}
#endif
@@ -8447,11 +8608,18 @@ DEFINE_COMPILER;
backtrack_common *backtrack;
recurse_entry *entry = common->entries;
recurse_entry *prev = NULL;
+PCRE2_SPTR end;
sljit_sw start = GET(cc, 1);
+sljit_uw arg_size;
PCRE2_SPTR start_cc;
BOOL needs_control_head;
-PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
+end = cc + 1 + LINK_SIZE;
+
+while (*end == OP_CREF)
+ end += 1 + IMM2_SIZE;
+
+PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, end);
/* Inlining simple patterns. */
if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
@@ -8459,12 +8627,15 @@ if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head
start_cc = common->start + start;
compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
- return cc + 1 + LINK_SIZE;
+ return end;
}
+cc += 1 + LINK_SIZE;
+arg_size = (sljit_uw)IN_UCHARS(end - cc);
while (entry != NULL)
{
- if (entry->start == start)
+ if (entry->start == start && entry->arg_size == arg_size
+ && (arg_size == 0 || memcmp(cc, entry->arg_start, arg_size) == 0))
break;
prev = entry;
entry = entry->next;
@@ -8474,13 +8645,15 @@ if (entry == NULL)
{
entry = sljit_alloc_memory(compiler, sizeof(recurse_entry));
if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
- return NULL;
+ return end;
entry->next = NULL;
entry->entry_label = NULL;
entry->backtrack_label = NULL;
entry->entry_calls = NULL;
entry->backtrack_calls = NULL;
entry->start = start;
+ entry->arg_start = cc;
+ entry->arg_size = arg_size;
if (prev != NULL)
prev->next = entry;
@@ -8497,7 +8670,7 @@ else
/* Leave if the match is failed. */
add_jump(compiler, &backtrack->own_backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0));
BACKTRACK_AS(recurse_backtrack)->matchingpath = LABEL();
-return cc + 1 + LINK_SIZE;
+return end;
}
static sljit_s32 SLJIT_FUNC do_callout_jit(struct jit_arguments *arguments, pcre2_callout_block *callout_block, PCRE2_SPTR *jit_ovector)
@@ -8567,7 +8740,7 @@ unsigned int callout_length = (*cc == OP_CALLOUT)
sljit_sw value1;
sljit_sw value2;
sljit_sw value3;
-sljit_uw callout_arg_size = (common->re->top_bracket + 1) * 2 * SSIZE_OF(sw);
+sljit_s32 callout_arg_size = (common->re->top_bracket + 1) * 2 * SSIZE_OF(sw); /* top_bracket is uint16 so maximum is 1MiB */
PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
@@ -8660,7 +8833,7 @@ if (*cc == OP_REVERSE)
else
{
SLJIT_ASSERT(*cc == OP_VREVERSE);
- PUSH_BACKTRACK(sizeof(vreverse_backtrack), cc, NULL);
+ PUSH_BACKTRACK(sizeof(vreverse_backtrack), cc, cc + 1 + 2 * IMM2_SIZE);
reverse_failed = &backtrack->own_backtracks;
lmin = GET2(cc, 1);
@@ -9304,7 +9477,7 @@ if (common->capture_last_ptr != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
stacksize++;
}
-if (common->optimized_cbracket[offset >> 1] == 0)
+if (!is_optimized_cbracket(common, offset >> 1))
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset));
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1));
@@ -9478,7 +9651,7 @@ if (opcode == OP_CBRA || opcode == OP_SCBRA)
{
/* Capturing brackets has a pre-allocated space. */
offset = GET2(ccbegin, 1 + LINK_SIZE);
- if (common->optimized_cbracket[offset] == 0)
+ if (!is_optimized_cbracket(common, offset))
{
private_data_ptr = OVECTOR_PRIV(offset);
offset <<= 1;
@@ -9659,7 +9832,7 @@ if (opcode == OP_ONCE)
else if (opcode == OP_CBRA || opcode == OP_SCBRA)
{
/* Saving the previous values. */
- if (common->optimized_cbracket[offset >> 1] != 0)
+ if (is_optimized_cbracket(common, offset >> 1))
{
SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
allocate_stack(common, 2);
@@ -9896,6 +10069,8 @@ if (opcode == OP_COND || opcode == OP_SCOND)
assert->common.cc = matchingpath;
BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
+ return NULL;
}
}
@@ -9936,7 +10111,7 @@ if (offset != 0)
{
if (common->capture_last_ptr != 0)
stacksize++;
- if (common->optimized_cbracket[offset >> 1] == 0)
+ if (!is_optimized_cbracket(common, offset >> 1))
stacksize += 2;
}
if (has_alternatives && opcode != OP_ONCE)
@@ -9980,14 +10155,14 @@ if (has_alternatives)
if (i <= 3)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
else
- BACKTRACK_AS(bracket_backtrack)->matching_mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
+ BACKTRACK_AS(bracket_backtrack)->matching_mov_addr = sljit_emit_op_addr(compiler, SLJIT_MOV_ADDR, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
}
if (ket != OP_KETRMAX)
BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
}
/* Must be after the matchingpath label. */
-if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
+if (offset != 0 && is_optimized_cbracket(common, offset >> 1))
{
SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), STR_PTR, 0);
@@ -10149,7 +10324,7 @@ switch(opcode)
offset = GET2(cc, 1 + LINK_SIZE);
/* This case cannot be optimized in the same way as
normal capturing brackets. */
- SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
+ SLJIT_ASSERT(!is_optimized_cbracket(common, offset));
cbraprivptr = OVECTOR_PRIV(offset);
offset <<= 1;
ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
@@ -11331,7 +11506,7 @@ static SLJIT_INLINE PCRE2_SPTR compile_close_matchingpath(compiler_common *commo
{
DEFINE_COMPILER;
int offset = GET2(cc, 1);
-BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
+BOOL optimized_cbracket = is_optimized_cbracket(common, offset);
/* Data will be discarded anyway... */
if (common->currententry != NULL)
@@ -12202,7 +12377,7 @@ if (offset != 0)
{
if (common->capture_last_ptr != 0)
{
- SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
+ SLJIT_ASSERT(!is_optimized_cbracket(common, offset >> 1));
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->capture_last_ptr, TMP1, 0);
@@ -12211,7 +12386,7 @@ if (offset != 0)
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset), TMP2, 0);
OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1), TMP1, 0);
}
- else if (common->optimized_cbracket[offset >> 1] == 0)
+ else if (!is_optimized_cbracket(common, offset >> 1))
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
@@ -12393,7 +12568,7 @@ if (has_alternatives)
{
if (common->capture_last_ptr != 0)
stacksize++;
- if (common->optimized_cbracket[offset >> 1] == 0)
+ if (!is_optimized_cbracket(common, offset >> 1))
stacksize += 2;
}
if (opcode != OP_ONCE)
@@ -12427,10 +12602,10 @@ if (has_alternatives)
if (alt_max <= 3)
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, alt_count);
else
- mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
+ mov_addr = sljit_emit_op_addr(compiler, SLJIT_MOV_ADDR, SLJIT_MEM1(STACK_TOP), STACK(stacksize));
}
- if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
+ if (offset != 0 && ket == OP_KETRMAX && is_optimized_cbracket(common, offset >> 1))
{
/* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
@@ -12492,7 +12667,7 @@ if (has_alternatives)
if (offset != 0)
{
/* Using both tmp register is better for instruction scheduling. */
- if (common->optimized_cbracket[offset >> 1] != 0)
+ if (is_optimized_cbracket(common, offset >> 1))
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
@@ -12670,6 +12845,8 @@ if (current->cc[1] > OP_ASSERTBACK_NOT)
{
/* Manual call of compile_bracket_matchingpath and compile_bracket_backtrackingpath. */
compile_bracket_matchingpath(common, current->cc, current);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(common->compiler)))
+ return;
compile_bracket_backtrackingpath(common, current->top);
}
else
@@ -12679,6 +12856,8 @@ else
backtrack.matchingpath = CURRENT_AS(braminzero_backtrack)->matchingpath;
/* Manual call of compile_assert_matchingpath. */
compile_assert_matchingpath(common, current->cc, &backtrack, FALSE);
+ if (SLJIT_UNLIKELY(sljit_get_compiler_error(common->compiler)))
+ return;
}
SLJIT_ASSERT(!current->simple_backtracks && !current->own_backtracks);
}
@@ -13093,7 +13272,7 @@ while (1)
if (alt_max > 1 || (recurse_flags & recurse_flag_accept_found))
{
if (alt_max > 3)
- mov_addr = sljit_emit_mov_addr(compiler, SLJIT_MEM1(STACK_TOP), STACK(1));
+ mov_addr = sljit_emit_op_addr(compiler, SLJIT_MOV_ADDR, SLJIT_MEM1(STACK_TOP), STACK(1));
else
OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, alt_count);
}
@@ -13360,7 +13539,8 @@ if (private_data_length > ~(sljit_uw)0 / sizeof(sljit_s32))
private_data_length *= sizeof(sljit_s32);
/* Align to 32 bit. */
-total_length = ((re->top_bracket + 1) + (sljit_uw)(sizeof(sljit_s32) - 1)) & ~(sljit_uw)(sizeof(sljit_s32) - 1);
+common->cbracket_bitset_length = ((re->top_bracket + 1) + (sljit_u32)7) & ~(sljit_u32)7;
+total_length = common->cbracket_bitset_length << 1;
if (~(sljit_uw)0 - private_data_length < total_length)
return PCRE2_ERROR_NOMEMORY;
@@ -13370,12 +13550,13 @@ if (!common->private_data_ptrs)
return PCRE2_ERROR_NOMEMORY;
memset(common->private_data_ptrs, 0, private_data_length);
-common->optimized_cbracket = ((sljit_u8 *)common->private_data_ptrs) + private_data_length;
+common->optimized_cbrackets = ((sljit_u8 *)common->private_data_ptrs) + private_data_length;
#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
-memset(common->optimized_cbracket, 0, re->top_bracket + 1);
+memset(common->optimized_cbrackets, 0, common->cbracket_bitset_length);
#else
-memset(common->optimized_cbracket, 1, re->top_bracket + 1);
+memset(common->optimized_cbrackets, 0xff, common->cbracket_bitset_length);
#endif
+common->cbracket_bitset = common->optimized_cbrackets + common->cbracket_bitset_length;
SLJIT_ASSERT(*common->start == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
#if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
@@ -13440,7 +13621,7 @@ if (common->start_ptr == 0)
/* Capturing brackets cannot be optimized if callouts are allowed. */
if (common->capture_last_ptr != 0)
- memset(common->optimized_cbracket, 0, re->top_bracket + 1);
+ memset(common->optimized_cbrackets, 0, common->cbracket_bitset_length);
SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
@@ -13591,6 +13772,34 @@ common->accept_label = LABEL();
if (common->accept != NULL)
set_jumps(common->accept, common->accept_label);
+/* Fail if we detect that the start position was moved to be either after
+the end position (\K in lookahead) or before the start offset (\K in
+lookbehind). */
+
+if (common->has_set_som &&
+ (common->re->extra_options & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) == 0)
+ {
+ if (HAS_VIRTUAL_REGISTERS)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
+ }
+ else
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(ARGUMENTS), SLJIT_OFFSETOF(jit_arguments, str));
+ }
+ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(0));
+
+ /* (ovector[0] < jit_arguments->str)? */
+ OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP2, 0, TMP1, 0);
+ /* Unconditionally set R0 (aka TMP1), in between the comparison that needs to
+ use TMP1, but before the jump. */
+ OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE2_ERROR_BAD_BACKSLASH_K);
+ add_jump(compiler, &common->abort, JUMP(SLJIT_LESS));
+ /* (ovector[0] > STR_PTR)? NB. ovector[1] hasn't yet been set to STR_PTR. */
+ add_jump(compiler, &common->abort, CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0));
+ }
+
/* This means we have a match. Update the ovector. */
copy_ovector(common, re->top_bracket + 1);
common->quit_label = common->abort_label = LABEL();
@@ -14099,7 +14308,7 @@ return 0;
#define INCLUDED_FROM_PCRE2_JIT_COMPILE
-#include "pcre2_jit_match.c"
-#include "pcre2_jit_misc.c"
+#include "pcre2_jit_match_inc.h"
+#include "pcre2_jit_misc_inc.h"
/* End of pcre2_jit_compile.c */
diff --git a/src/3rdparty/pcre2/src/pcre2_jit_match.c b/src/3rdparty/pcre2/src/pcre2_jit_match_inc.h
index 8867f768df1..32d4c8a5e1a 100644
--- a/src/3rdparty/pcre2/src/pcre2_jit_match.c
+++ b/src/3rdparty/pcre2/src/pcre2_jit_match_inc.h
@@ -99,9 +99,8 @@ pcre2_jit_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
(void)length;
(void)start_offset;
(void)options;
-(void)match_data;
(void)mcontext;
-return PCRE2_ERROR_JIT_BADOPTION;
+return match_data->rc = PCRE2_ERROR_JIT_BADOPTION;
#else /* SUPPORT_JIT */
@@ -124,7 +123,7 @@ else if ((options & PCRE2_PARTIAL_SOFT) != 0)
index = 1;
if (functions == NULL || functions->executable_funcs[index] == NULL)
- return PCRE2_ERROR_JIT_BADOPTION;
+ return match_data->rc = PCRE2_ERROR_JIT_BADOPTION;
/* Sanity checks should be handled by pcre2_match. */
arguments.str = subject + start_offset;
@@ -176,14 +175,17 @@ else
if (rc > (int)oveccount)
rc = 0;
match_data->code = re;
-match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL;
+match_data->subject =
+ (rc >= 0 || rc == PCRE2_ERROR_NOMATCH || rc == PCRE2_ERROR_PARTIAL)? subject : NULL;
match_data->subject_length = length;
+match_data->start_offset = start_offset;
match_data->rc = rc;
match_data->startchar = arguments.startchar_ptr - subject;
match_data->leftchar = 0;
match_data->rightchar = 0;
match_data->mark = arguments.mark_ptr;
match_data->matchedby = PCRE2_MATCHEDBY_JIT;
+match_data->options = options;
#if defined(__has_feature)
#if __has_feature(memory_sanitizer)
@@ -197,4 +199,4 @@ return match_data->rc;
#endif /* SUPPORT_JIT */
}
-/* End of pcre2_jit_match.c */
+/* End of pcre2_jit_match_inc.h */
diff --git a/src/3rdparty/pcre2/src/pcre2_jit_misc.c b/src/3rdparty/pcre2/src/pcre2_jit_misc_inc.h
index c3abc0b33bd..0225fc6baf2 100644
--- a/src/3rdparty/pcre2/src/pcre2_jit_misc.c
+++ b/src/3rdparty/pcre2/src/pcre2_jit_misc_inc.h
@@ -231,4 +231,4 @@ return executable_sizes[0] + executable_sizes[1] + executable_sizes[2];
#endif
}
-/* End of pcre2_jit_misc.c */
+/* End of pcre2_jit_misc_inc.h */
diff --git a/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h b/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h
deleted file mode 100644
index 1389a16573d..00000000000
--- a/src/3rdparty/pcre2/src/pcre2_jit_neon_inc.h
+++ /dev/null
@@ -1,354 +0,0 @@
-/*************************************************
-* Perl-Compatible Regular Expressions *
-*************************************************/
-
-/* PCRE is a library of functions to support regular expressions whose syntax
-and semantics are as close as possible to those of the Perl 5 language.
-
- Written by Philip Hazel
- This module by Zoltan Herczeg and Sebastian Pop
- Original API code Copyright (c) 1997-2012 University of Cambridge
- New API code Copyright (c) 2016-2019 University of Cambridge
-
------------------------------------------------------------------------------
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- * Neither the name of the University of Cambridge nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
------------------------------------------------------------------------------
-*/
-
-# if defined(FFCS)
-# if defined(FF_UTF)
-# define FF_FUN ffcs_utf
-# else
-# define FF_FUN ffcs
-# endif
-
-# elif defined(FFCS_2)
-# if defined(FF_UTF)
-# define FF_FUN ffcs_2_utf
-# else
-# define FF_FUN ffcs_2
-# endif
-
-# elif defined(FFCS_MASK)
-# if defined(FF_UTF)
-# define FF_FUN ffcs_mask_utf
-# else
-# define FF_FUN ffcs_mask
-# endif
-
-# elif defined(FFCPS_0)
-# if defined (FF_UTF)
-# define FF_FUN ffcps_0_utf
-# else
-# define FF_FUN ffcps_0
-# endif
-
-# elif defined (FFCPS_1)
-# if defined (FF_UTF)
-# define FF_FUN ffcps_1_utf
-# else
-# define FF_FUN ffcps_1
-# endif
-
-# elif defined (FFCPS_DEFAULT)
-# if defined (FF_UTF)
-# define FF_FUN ffcps_default_utf
-# else
-# define FF_FUN ffcps_default
-# endif
-# endif
-
-#if (defined(__GNUC__) && defined(__SANITIZE_ADDRESS__) && __SANITIZE_ADDRESS__ ) \
- || (defined(__clang__) \
- && ((__clang_major__ == 3 && __clang_minor__ >= 3) || (__clang_major__ > 3)))
-__attribute__((no_sanitize_address))
-#endif
-static sljit_u8* SLJIT_FUNC FF_FUN(sljit_u8 *str_end, sljit_u8 **str_ptr, sljit_uw offs1, sljit_uw offs2, sljit_uw chars)
-#undef FF_FUN
-{
-quad_word qw;
-int_char ic;
-
-SLJIT_UNUSED_ARG(offs1);
-SLJIT_UNUSED_ARG(offs2);
-
-ic.x = chars;
-
-#if defined(FFCS)
-sljit_u8 c1 = ic.c.c1;
-vect_t vc1 = VDUPQ(c1);
-
-#elif defined(FFCS_2)
-sljit_u8 c1 = ic.c.c1;
-vect_t vc1 = VDUPQ(c1);
-sljit_u8 c2 = ic.c.c2;
-vect_t vc2 = VDUPQ(c2);
-
-#elif defined(FFCS_MASK)
-sljit_u8 c1 = ic.c.c1;
-vect_t vc1 = VDUPQ(c1);
-sljit_u8 mask = ic.c.c2;
-vect_t vmask = VDUPQ(mask);
-#endif
-
-#if defined(FFCPS)
-compare_type compare1_type = compare_match1;
-compare_type compare2_type = compare_match1;
-vect_t cmp1a, cmp1b, cmp2a, cmp2b;
-const sljit_u32 diff = IN_UCHARS(offs1 - offs2);
-PCRE2_UCHAR char1a = ic.c.c1;
-PCRE2_UCHAR char2a = ic.c.c3;
-
-# ifdef FFCPS_CHAR1A2A
-cmp1a = VDUPQ(char1a);
-cmp2a = VDUPQ(char2a);
-cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
-cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
-# else
-PCRE2_UCHAR char1b = ic.c.c2;
-PCRE2_UCHAR char2b = ic.c.c4;
-if (char1a == char1b)
- {
- cmp1a = VDUPQ(char1a);
- cmp1b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
- }
-else
- {
- sljit_u32 bit1 = char1a ^ char1b;
- if (is_powerof2(bit1))
- {
- compare1_type = compare_match1i;
- cmp1a = VDUPQ(char1a | bit1);
- cmp1b = VDUPQ(bit1);
- }
- else
- {
- compare1_type = compare_match2;
- cmp1a = VDUPQ(char1a);
- cmp1b = VDUPQ(char1b);
- }
- }
-
-if (char2a == char2b)
- {
- cmp2a = VDUPQ(char2a);
- cmp2b = VDUPQ(0); /* to avoid errors on older compilers -Werror=maybe-uninitialized */
- }
-else
- {
- sljit_u32 bit2 = char2a ^ char2b;
- if (is_powerof2(bit2))
- {
- compare2_type = compare_match1i;
- cmp2a = VDUPQ(char2a | bit2);
- cmp2b = VDUPQ(bit2);
- }
- else
- {
- compare2_type = compare_match2;
- cmp2a = VDUPQ(char2a);
- cmp2b = VDUPQ(char2b);
- }
- }
-# endif
-
-*str_ptr += IN_UCHARS(offs1);
-#endif
-
-#if PCRE2_CODE_UNIT_WIDTH != 8
-vect_t char_mask = VDUPQ(0xff);
-#endif
-
-#if defined(FF_UTF)
-restart:;
-#endif
-
-#if defined(FFCPS)
-if (*str_ptr >= str_end)
- return NULL;
-sljit_u8 *p1 = *str_ptr - diff;
-#endif
-sljit_s32 align_offset = ((uint64_t)*str_ptr & 0xf);
-*str_ptr = (sljit_u8 *) ((uint64_t)*str_ptr & ~0xf);
-vect_t data = VLD1Q(*str_ptr);
-#if PCRE2_CODE_UNIT_WIDTH != 8
-data = VANDQ(data, char_mask);
-#endif
-
-#if defined(FFCS)
-vect_t eq = VCEQQ(data, vc1);
-
-#elif defined(FFCS_2)
-vect_t eq1 = VCEQQ(data, vc1);
-vect_t eq2 = VCEQQ(data, vc2);
-vect_t eq = VORRQ(eq1, eq2);
-
-#elif defined(FFCS_MASK)
-vect_t eq = VORRQ(data, vmask);
-eq = VCEQQ(eq, vc1);
-
-#elif defined(FFCPS)
-# if defined(FFCPS_DIFF1)
-vect_t prev_data = data;
-# endif
-
-vect_t data2;
-if (p1 < *str_ptr)
- {
- data2 = VLD1Q(*str_ptr - diff);
-#if PCRE2_CODE_UNIT_WIDTH != 8
- data2 = VANDQ(data2, char_mask);
-#endif
- }
-else
- data2 = shift_left_n_lanes(data, offs1 - offs2);
-
-if (compare1_type == compare_match1)
- data = VCEQQ(data, cmp1a);
-else
- data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
-
-if (compare2_type == compare_match1)
- data2 = VCEQQ(data2, cmp2a);
-else
- data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
-
-vect_t eq = VANDQ(data, data2);
-#endif
-
-VST1Q(qw.mem, eq);
-/* Ignore matches before the first STR_PTR. */
-if (align_offset < 8)
- {
- qw.dw[0] >>= align_offset * 8;
- if (qw.dw[0])
- {
- *str_ptr += align_offset + __builtin_ctzll(qw.dw[0]) / 8;
- goto match;
- }
- if (qw.dw[1])
- {
- *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
- goto match;
- }
- }
-else
- {
- qw.dw[1] >>= (align_offset - 8) * 8;
- if (qw.dw[1])
- {
- *str_ptr += align_offset + __builtin_ctzll(qw.dw[1]) / 8;
- goto match;
- }
- }
-*str_ptr += 16;
-
-while (*str_ptr < str_end)
- {
- vect_t orig_data = VLD1Q(*str_ptr);
-#if PCRE2_CODE_UNIT_WIDTH != 8
- orig_data = VANDQ(orig_data, char_mask);
-#endif
- data = orig_data;
-
-#if defined(FFCS)
- eq = VCEQQ(data, vc1);
-
-#elif defined(FFCS_2)
- eq1 = VCEQQ(data, vc1);
- eq2 = VCEQQ(data, vc2);
- eq = VORRQ(eq1, eq2);
-
-#elif defined(FFCS_MASK)
- eq = VORRQ(data, vmask);
- eq = VCEQQ(eq, vc1);
-#endif
-
-#if defined(FFCPS)
-# if defined (FFCPS_DIFF1)
- data2 = VEXTQ(prev_data, data, VECTOR_FACTOR - 1);
-# else
- data2 = VLD1Q(*str_ptr - diff);
-# if PCRE2_CODE_UNIT_WIDTH != 8
- data2 = VANDQ(data2, char_mask);
-# endif
-# endif
-
-# ifdef FFCPS_CHAR1A2A
- data = VCEQQ(data, cmp1a);
- data2 = VCEQQ(data2, cmp2a);
-# else
- if (compare1_type == compare_match1)
- data = VCEQQ(data, cmp1a);
- else
- data = fast_forward_char_pair_compare(compare1_type, data, cmp1a, cmp1b);
- if (compare2_type == compare_match1)
- data2 = VCEQQ(data2, cmp2a);
- else
- data2 = fast_forward_char_pair_compare(compare2_type, data2, cmp2a, cmp2b);
-# endif
-
- eq = VANDQ(data, data2);
-#endif
-
- VST1Q(qw.mem, eq);
- if (qw.dw[0])
- *str_ptr += __builtin_ctzll(qw.dw[0]) / 8;
- else if (qw.dw[1])
- *str_ptr += 8 + __builtin_ctzll(qw.dw[1]) / 8;
- else {
- *str_ptr += 16;
-#if defined (FFCPS_DIFF1)
- prev_data = orig_data;
-#endif
- continue;
- }
-
-match:;
- if (*str_ptr >= str_end)
- /* Failed match. */
- return NULL;
-
-#if defined(FF_UTF)
- if (utf_continue((PCRE2_SPTR)*str_ptr - offs1))
- {
- /* Not a match. */
- *str_ptr += IN_UCHARS(1);
- goto restart;
- }
-#endif
-
- /* Match. */
-#if defined (FFCPS)
- *str_ptr -= IN_UCHARS(offs1);
-#endif
- return *str_ptr;
- }
-
-/* Failed match. */
-return NULL;
-}
diff --git a/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h b/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h
index 66e93cd5996..0a24cdad813 100644
--- a/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h
+++ b/src/3rdparty/pcre2/src/pcre2_jit_simd_inc.h
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
#if !(defined SUPPORT_VALGRIND)
#if ((defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) \
+ || (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64) \
|| (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X) \
|| (defined SLJIT_CONFIG_LOONGARCH_64 && SLJIT_CONFIG_LOONGARCH_64))
@@ -100,7 +101,7 @@ return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00);
}
#endif
-#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_S390X */
+#endif /* SLJIT_CONFIG_X86 || SLJIT_CONFIG_ARM_64 || SLJIT_CONFIG_S390X || SLJIT_CONFIG_LOONGARCH_64 */
#if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86)
@@ -228,7 +229,14 @@ switch (step)
}
}
+/* The AVX2 code path is currently disabled.
#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD))
+*/
+#if defined(SLJIT_CONFIG_X86_64) && SLJIT_CONFIG_X86_64
+#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1
+#else
+#define JIT_HAS_FAST_FORWARD_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_FPU))
+#endif
static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
{
@@ -246,10 +254,10 @@ struct sljit_jump *quit;
struct sljit_jump *partial_quit[2];
vector_compare_type compare_type = vector_compare_match1;
sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);
-sljit_s32 data_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);
-sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);
-sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);
-sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);
+sljit_s32 data_ind = sljit_get_register_index(reg_type, SLJIT_VR0);
+sljit_s32 cmp1_ind = sljit_get_register_index(reg_type, SLJIT_VR1);
+sljit_s32 cmp2_ind = sljit_get_register_index(reg_type, SLJIT_VR2);
+sljit_s32 tmp_ind = sljit_get_register_index(reg_type, SLJIT_VR3);
sljit_u32 bit = 0;
int i;
@@ -365,7 +373,14 @@ if (common->utf && offset > 0)
#endif
}
+/* The AVX2 code path is currently disabled.
#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD))
+*/
+#if defined(SLJIT_CONFIG_X86_64) && SLJIT_CONFIG_X86_64
+#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD 1
+#else
+#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_FPU))
+#endif
static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
{
@@ -380,10 +395,10 @@ struct sljit_jump *quit;
jump_list *not_found = NULL;
vector_compare_type compare_type = vector_compare_match1;
sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);
-sljit_s32 data_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);
-sljit_s32 cmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);
-sljit_s32 cmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);
-sljit_s32 tmp_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);
+sljit_s32 data_ind = sljit_get_register_index(reg_type, SLJIT_VR0);
+sljit_s32 cmp1_ind = sljit_get_register_index(reg_type, SLJIT_VR1);
+sljit_s32 cmp2_ind = sljit_get_register_index(reg_type, SLJIT_VR2);
+sljit_s32 tmp_ind = sljit_get_register_index(reg_type, SLJIT_VR3);
sljit_u32 bit = 0;
int i;
@@ -471,7 +486,14 @@ return not_found;
#ifndef _WIN64
+/* The AVX2 code path is currently disabled.
#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_SIMD))
+*/
+#if defined(SLJIT_CONFIG_X86_64) && SLJIT_CONFIG_X86_64
+#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1
+#else
+#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD (sljit_has_cpu_feature(SLJIT_HAS_FPU))
+#endif
static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1,
PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
@@ -488,14 +510,14 @@ sljit_u32 bit1 = 0;
sljit_u32 bit2 = 0;
sljit_u32 diff = IN_UCHARS(offs1 - offs2);
sljit_s32 tmp1_reg_ind = sljit_get_register_index(SLJIT_GP_REGISTER, TMP1);
-sljit_s32 data1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);
-sljit_s32 data2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);
-sljit_s32 cmp1a_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);
-sljit_s32 cmp2a_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);
-sljit_s32 cmp1b_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR4);
-sljit_s32 cmp2b_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR5);
-sljit_s32 tmp1_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR6);
-sljit_s32 tmp2_ind = sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_TMP_DEST_VREG);
+sljit_s32 data1_ind = sljit_get_register_index(reg_type, SLJIT_VR0);
+sljit_s32 data2_ind = sljit_get_register_index(reg_type, SLJIT_VR1);
+sljit_s32 cmp1a_ind = sljit_get_register_index(reg_type, SLJIT_VR2);
+sljit_s32 cmp2a_ind = sljit_get_register_index(reg_type, SLJIT_VR3);
+sljit_s32 cmp1b_ind = sljit_get_register_index(reg_type, SLJIT_VR4);
+sljit_s32 cmp2b_ind = sljit_get_register_index(reg_type, SLJIT_VR5);
+sljit_s32 tmp1_ind = sljit_get_register_index(reg_type, SLJIT_VR6);
+sljit_s32 tmp2_ind = sljit_get_register_index(reg_type, SLJIT_TMP_DEST_VREG);
struct sljit_label *start;
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
struct sljit_label *restart;
@@ -692,8 +714,8 @@ sljit_emit_simd_mov(compiler, reg_type, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_
for (i = 0; i < 4; i++)
{
- fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp2_ind);
- fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp1_ind);
+ fast_forward_char_pair_sse2_compare(compiler, compare1_type, reg_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);
+ fast_forward_char_pair_sse2_compare(compiler, compare2_type, reg_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);
}
sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | reg_type, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0);
@@ -744,286 +766,284 @@ if (common->match_end_ptr != 0)
#if (defined SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 && (defined __ARM_NEON || defined __ARM_NEON__))
-#include <arm_neon.h>
-
-typedef union {
- unsigned int x;
- struct { unsigned char c1, c2, c3, c4; } c;
-} int_char;
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-static SLJIT_INLINE int utf_continue(PCRE2_SPTR s)
-{
#if PCRE2_CODE_UNIT_WIDTH == 8
-return (*s & 0xc0) == 0x80;
+#define PCRE2_REPLICATE_TYPE (SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_8)
#elif PCRE2_CODE_UNIT_WIDTH == 16
-return (*s & 0xfc00) == 0xdc00;
+#define PCRE2_REPLICATE_TYPE (SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_16)
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+#define PCRE2_REPLICATE_TYPE (SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_32)
#else
-#error "Unknown code width"
+#error "Unsupported unit width"
#endif
-}
-#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */
+#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1
+
+static void fast_forward_char_pair_sse2_compare(struct sljit_compiler *compiler, vector_compare_type compare_type,
+ int step, sljit_u32 dst_ind, sljit_u32 cmp1_ind, sljit_u32 cmp2_ind, sljit_u32 tmp_ind)
+{
+sljit_u32 instruction;
#if PCRE2_CODE_UNIT_WIDTH == 8
-# define VECTOR_FACTOR 16
-# define vect_t uint8x16_t
-# define VLD1Q(X) vld1q_u8((sljit_u8 *)(X))
-# define VCEQQ vceqq_u8
-# define VORRQ vorrq_u8
-# define VST1Q vst1q_u8
-# define VDUPQ vdupq_n_u8
-# define VEXTQ vextq_u8
-# define VANDQ vandq_u8
-typedef union {
- uint8_t mem[16];
- uint64_t dw[2];
-} quad_word;
+sljit_u32 size = 0 << 22;
#elif PCRE2_CODE_UNIT_WIDTH == 16
-# define VECTOR_FACTOR 8
-# define vect_t uint16x8_t
-# define VLD1Q(X) vld1q_u16((sljit_u16 *)(X))
-# define VCEQQ vceqq_u16
-# define VORRQ vorrq_u16
-# define VST1Q vst1q_u16
-# define VDUPQ vdupq_n_u16
-# define VEXTQ vextq_u16
-# define VANDQ vandq_u16
-typedef union {
- uint16_t mem[8];
- uint64_t dw[2];
-} quad_word;
+sljit_u32 size = 1 << 22;
+#elif PCRE2_CODE_UNIT_WIDTH == 32
+sljit_u32 size = 2 << 22;
#else
-# define VECTOR_FACTOR 4
-# define vect_t uint32x4_t
-# define VLD1Q(X) vld1q_u32((sljit_u32 *)(X))
-# define VCEQQ vceqq_u32
-# define VORRQ vorrq_u32
-# define VST1Q vst1q_u32
-# define VDUPQ vdupq_n_u32
-# define VEXTQ vextq_u32
-# define VANDQ vandq_u32
-typedef union {
- uint32_t mem[4];
- uint64_t dw[2];
-} quad_word;
+#error "Unsupported unit width"
#endif
-#define FFCS
-#include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCS
+SLJIT_ASSERT(step >= 0 && step <= 2);
-#define FFCS_2
-#include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCS_2
+if (step == 1)
+ {
+ /* CMEQ */
+ instruction = 0x6e208c00 | size | (cmp1_ind << 16) | (dst_ind << 5) | dst_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+ return;
+ }
-#define FFCS_MASK
-#include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCS_MASK
+if (compare_type != vector_compare_match2)
+ {
+ if (step == 0 && compare_type == vector_compare_match1i)
+ {
+ /* ORR */
+ instruction = 0x4ea01c00 | (cmp2_ind << 16) | (dst_ind << 5) | dst_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+ }
+ return;
+ }
-#define JIT_HAS_FAST_FORWARD_CHAR_SIMD 1
+switch (step)
+ {
+ case 0:
+ /* CMEQ */
+ instruction = 0x6e208c00 | size | (cmp2_ind << 16) | (dst_ind << 5) | tmp_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+ return;
+
+ case 2:
+ /* ORR */
+ instruction = 0x4ea01c00 | (tmp_ind << 16) | (dst_ind << 5) | dst_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+ return;
+ }
+}
static void fast_forward_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2, sljit_s32 offset)
{
DEFINE_COMPILER;
-int_char ic;
-struct sljit_jump *partial_quit, *quit;
-/* Save temporary registers. */
-SLJIT_ASSERT(common->locals_size >= 2 * (int)sizeof(sljit_sw));
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0);
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL1, TMP3, 0);
+sljit_u32 instruction;
+struct sljit_label *start;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_label *restart;
+#endif
+struct sljit_jump *quit;
+struct sljit_jump *partial_quit[2];
+vector_compare_type compare_type = vector_compare_match1;
+sljit_u32 data_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);
+sljit_u32 cmp1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);
+sljit_u32 cmp2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);
+sljit_u32 tmp_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);
+sljit_u32 bit = 0;
+int i;
-/* Prepare function arguments */
-OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);
-GET_LOCAL_BASE(SLJIT_R1, 0, LOCAL0);
-OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_IMM, offset);
+SLJIT_UNUSED_ARG(offset);
-if (char1 == char2)
+if (char1 != char2)
{
- ic.c.c1 = char1;
- ic.c.c2 = char2;
- OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
+ bit = char1 ^ char2;
+ compare_type = vector_compare_match1i;
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf && offset > 0)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_utf));
- else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs));
-#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs));
-#endif
- }
-else
- {
- PCRE2_UCHAR mask = char1 ^ char2;
- if (is_powerof2(mask))
+ if (!is_powerof2(bit))
{
- ic.c.c1 = char1 | mask;
- ic.c.c2 = mask;
- OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
-
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf && offset > 0)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_mask_utf));
- else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_mask));
-#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_mask));
-#endif
+ bit = 0;
+ compare_type = vector_compare_match2;
}
- else
- {
- ic.c.c1 = char1;
- ic.c.c2 = char2;
- OP1(SLJIT_MOV, SLJIT_R4, 0, SLJIT_IMM, ic.x);
+ }
+
+partial_quit[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
+if (common->mode == PCRE2_JIT_COMPLETE)
+ add_jump(compiler, &common->failed_match, partial_quit[0]);
+
+/* First part (unaligned start) */
+if (char1 != char2)
+ sljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit != 0 ? bit : char2);
+sljit_emit_op1(compiler, SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit);
+
+if (char1 != char2)
+ sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR2, TMP2, 0);
+sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR1, TMP1, 0);
+
+OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf && offset > 0)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_2_utf));
- else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_2));
-#else
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcs_2));
+restart = LABEL();
#endif
- }
- }
-/* Restore registers. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);
-OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_SP), LOCAL1);
-/* Check return value. */
-partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~(sljit_sw)0xf);
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
+
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);
+
+for (i = 0; i < 3; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* SHRN */
+instruction = 0x0f0c8400 | (data_ind << 5) | data_ind;
+sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+sljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);
+
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, TMP2, 0);
+
+quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
+
+/* Second part (aligned) */
+start = LABEL();
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
+
+partial_quit[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
if (common->mode == PCRE2_JIT_COMPLETE)
- add_jump(compiler, &common->failed_match, partial_quit);
+ add_jump(compiler, &common->failed_match, partial_quit[1]);
+
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);
+for (i = 0; i < 3; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* SHRN */
+instruction = 0x0f0c8400 | (data_ind << 5) | data_ind;
+sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+sljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);
+CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
+
+JUMPHERE(quit);
+
+sljit_emit_op1(compiler, SLJIT_CTZ, TMP1, 0, TMP1, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
-/* Fast forward STR_PTR to the result of memchr. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
if (common->mode != PCRE2_JIT_COMPLETE)
{
- quit = CMP(SLJIT_NOT_ZERO, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
- JUMPHERE(partial_quit);
+ JUMPHERE(partial_quit[0]);
+ JUMPHERE(partial_quit[1]);
OP2U(SLJIT_SUB | SLJIT_SET_GREATER, STR_PTR, 0, STR_END, 0);
SELECT(SLJIT_GREATER, STR_PTR, STR_END, 0, STR_PTR);
- JUMPHERE(quit);
}
-}
-
-typedef enum {
- compare_match1,
- compare_match1i,
- compare_match2,
-} compare_type;
+else
+ add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
-static inline vect_t fast_forward_char_pair_compare(compare_type ctype, vect_t dst, vect_t cmp1, vect_t cmp2)
-{
-if (ctype == compare_match2)
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+if (common->utf && offset > 0)
{
- vect_t tmp = dst;
- dst = VCEQQ(dst, cmp1);
- tmp = VCEQQ(tmp, cmp2);
- dst = VORRQ(dst, tmp);
- return dst;
- }
+ SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE);
-if (ctype == compare_match1i)
- dst = VORRQ(dst, cmp2);
-dst = VCEQQ(dst, cmp1);
-return dst;
-}
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offset));
-static SLJIT_INLINE sljit_u32 max_fast_forward_char_pair_offset(void)
-{
-#if PCRE2_CODE_UNIT_WIDTH == 8
-return 15;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
-return 7;
-#elif PCRE2_CODE_UNIT_WIDTH == 32
-return 3;
-#else
-#error "Unsupported unit width"
+ quit = jump_if_utf_char_start(compiler, TMP1);
+
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+ OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+ JUMPTO(SLJIT_JUMP, restart);
+
+ JUMPHERE(quit);
+ }
#endif
}
-/* ARM doesn't have a shift left across lanes. */
-static SLJIT_INLINE vect_t shift_left_n_lanes(vect_t a, sljit_u8 n)
+#define JIT_HAS_FAST_REQUESTED_CHAR_SIMD 1
+
+static jump_list *fast_requested_char_simd(compiler_common *common, PCRE2_UCHAR char1, PCRE2_UCHAR char2)
{
-vect_t zero = VDUPQ(0);
-SLJIT_ASSERT(0 < n && n < VECTOR_FACTOR);
-/* VEXTQ takes an immediate as last argument. */
-#define C(X) case X: return VEXTQ(zero, a, VECTOR_FACTOR - X);
-switch (n)
+DEFINE_COMPILER;
+sljit_u32 instruction;
+struct sljit_label *start;
+struct sljit_jump *quit;
+jump_list *not_found = NULL;
+vector_compare_type compare_type = vector_compare_match1;
+sljit_u32 data_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);
+sljit_u32 cmp1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);
+sljit_u32 cmp2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);
+sljit_u32 tmp_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);
+sljit_u32 bit = 0;
+int i;
+
+if (char1 != char2)
{
- C(1); C(2); C(3);
-#if PCRE2_CODE_UNIT_WIDTH != 32
- C(4); C(5); C(6); C(7);
-# if PCRE2_CODE_UNIT_WIDTH != 16
- C(8); C(9); C(10); C(11); C(12); C(13); C(14); C(15);
-# endif
-#endif
- default:
- /* Based on the ASSERT(0 < n && n < VECTOR_FACTOR) above, this won't
- happen. The return is still here for compilers to not warn. */
- return a;
+ bit = char1 ^ char2;
+ compare_type = vector_compare_match1i;
+
+ if (!is_powerof2(bit))
+ {
+ bit = 0;
+ compare_type = vector_compare_match2;
+ }
}
-}
-#define FFCPS
-#define FFCPS_DIFF1
-#define FFCPS_CHAR1A2A
+add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
-#define FFCPS_0
-#include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCPS_0
+/* First part (unaligned start) */
-#undef FFCPS_CHAR1A2A
+if (char1 != char2)
+ sljit_emit_op1(compiler, SLJIT_MOV, TMP3, 0, SLJIT_IMM, bit != 0 ? bit : char2);
+sljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, char1 | bit);
-#define FFCPS_1
-#include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCPS_1
+if (char1 != char2)
+ sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR2, TMP3, 0);
+sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR1, TMP2, 0);
-#undef FFCPS_DIFF1
+OP2(SLJIT_AND, TMP3, 0, TMP1, 0, SLJIT_IMM, ~(sljit_sw)0xf);
+OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf);
-#define FFCPS_DEFAULT
-#include "pcre2_jit_neon_inc.h"
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
-# define FF_UTF
-# include "pcre2_jit_neon_inc.h"
-# undef FF_UTF
-#endif
-#undef FFCPS
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(TMP3), 0);
+
+for (i = 0; i < 3; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* SHRN */
+instruction = 0x0f0c8400 | (data_ind << 5) | data_ind;
+sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+sljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);
+
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, TMP2, 0);
+
+quit = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
+
+/* Second part (aligned) */
+start = LABEL();
+
+OP2(SLJIT_ADD, TMP3, 0, TMP3, 0, SLJIT_IMM, 16);
+
+add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP3, 0, STR_END, 0));
+
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(TMP3), 0);
+
+for (i = 0; i < 3; i++)
+ fast_forward_char_pair_sse2_compare(compiler, compare_type, i, data_ind, cmp1_ind, cmp2_ind, tmp_ind);
+
+/* SHRN */
+instruction = 0x0f0c8400 | (data_ind << 5) | data_ind;
+sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+sljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);
+CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
+
+JUMPHERE(quit);
+
+sljit_emit_op1(compiler, SLJIT_CTZ, TMP1, 0, TMP1, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);
+OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0);
+add_jump(compiler, &not_found, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_END, 0));
+
+return not_found;
+}
#define JIT_HAS_FAST_FORWARD_CHAR_PAIR_SIMD 1
@@ -1031,81 +1051,214 @@ static void fast_forward_char_pair_simd(compiler_common *common, sljit_s32 offs1
PCRE2_UCHAR char1a, PCRE2_UCHAR char1b, sljit_s32 offs2, PCRE2_UCHAR char2a, PCRE2_UCHAR char2b)
{
DEFINE_COMPILER;
+sljit_u32 instruction;
+vector_compare_type compare1_type = vector_compare_match1;
+vector_compare_type compare2_type = vector_compare_match1;
+sljit_u32 bit1 = 0;
+sljit_u32 bit2 = 0;
sljit_u32 diff = IN_UCHARS(offs1 - offs2);
-struct sljit_jump *partial_quit;
-int_char ic;
-SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2);
-SLJIT_ASSERT(diff <= IN_UCHARS(max_fast_forward_char_pair_offset()));
-SLJIT_ASSERT(compiler->scratches == 5);
+sljit_u32 data1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR0);
+sljit_u32 data2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR1);
+sljit_u32 cmp1a_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR2);
+sljit_u32 cmp2a_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR3);
+sljit_u32 cmp1b_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR4);
+sljit_u32 cmp2b_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR5);
+sljit_u32 tmp1_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR6);
+sljit_u32 tmp2_ind = (sljit_u32)sljit_get_register_index(SLJIT_SIMD_REG_128, SLJIT_VR7);
+struct sljit_label *start;
+#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
+struct sljit_label *restart;
+#endif
+struct sljit_jump *jump[2];
+int i;
-/* Save temporary register STR_PTR. */
-OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCAL0, STR_PTR, 0);
+SLJIT_ASSERT(common->mode == PCRE2_JIT_COMPLETE && offs1 > offs2 && offs2 >= 0);
+SLJIT_ASSERT(diff <= (unsigned)IN_UCHARS(max_fast_forward_char_pair_offset()));
-/* Prepare arguments for the function call. */
-if (common->match_end_ptr == 0)
- OP1(SLJIT_MOV, SLJIT_R0, 0, STR_END, 0);
-else
+if (char1a != char1b)
{
- OP1(SLJIT_MOV, SLJIT_R0, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
- OP2(SLJIT_ADD, SLJIT_R0, 0, SLJIT_R0, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
+ bit1 = char1a ^ char1b;
+ compare1_type = vector_compare_match1i;
- OP2U(SLJIT_SUB | SLJIT_SET_LESS, STR_END, 0, SLJIT_R0, 0);
- SELECT(SLJIT_LESS, SLJIT_R0, STR_END, 0, SLJIT_R0);
+ if (!is_powerof2(bit1))
+ {
+ bit1 = 0;
+ compare1_type = vector_compare_match2;
+ }
}
-GET_LOCAL_BASE(SLJIT_R1, 0, LOCAL0);
-OP1(SLJIT_MOV_S32, SLJIT_R2, 0, SLJIT_IMM, offs1);
-OP1(SLJIT_MOV_S32, SLJIT_R3, 0, SLJIT_IMM, offs2);
-ic.c.c1 = char1a;
-ic.c.c2 = char1b;
-ic.c.c3 = char2a;
-ic.c.c4 = char2b;
-OP1(SLJIT_MOV_U32, SLJIT_R4, 0, SLJIT_IMM, ic.x);
+if (char2a != char2b)
+ {
+ bit2 = char2a ^ char2b;
+ compare2_type = vector_compare_match1i;
+
+ if (!is_powerof2(bit2))
+ {
+ bit2 = 0;
+ compare2_type = vector_compare_match2;
+ }
+ }
+
+/* Initialize. */
+if (common->match_end_ptr != 0)
+ {
+ OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr);
+ OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
+ OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(offs1 + 1));
+
+ OP2U(SLJIT_SUB | SLJIT_SET_LESS, TMP1, 0, STR_END, 0);
+ SELECT(SLJIT_LESS, STR_END, TMP1, 0, STR_END);
+ }
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+sljit_emit_op1(compiler, SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1a | bit1);
+sljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, char2a | bit2);
+sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR2, TMP1, 0);
+sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR3, TMP2, 0);
+
+if (char1a != char1b)
+ sljit_emit_op1(compiler, SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit1 != 0 ? bit1 : char1b);
+
+if (char2a != char2b)
+ sljit_emit_op1(compiler, SLJIT_MOV, TMP2, 0, SLJIT_IMM, bit2 != 0 ? bit2 : char2b);
+
+if (char1a != char1b)
+ sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR4, TMP1, 0);
+
+if (char2a != char2b)
+ sljit_emit_simd_replicate(compiler, PCRE2_REPLICATE_TYPE, SLJIT_VR5, TMP2, 0);
-if (diff == 1) {
- if (char1a == char1b && char2a == char2b) {
-#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_0_utf));
- else
-#endif
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_0));
- } else {
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_1_utf));
- else
+restart = LABEL();
#endif
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_1));
+
+OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, diff);
+OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
+OP2(SLJIT_AND, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, ~(sljit_sw)0xf);
+
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);
+
+jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, STR_PTR, 0);
+
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff);
+jump[1] = JUMP(SLJIT_JUMP);
+
+JUMPHERE(jump[0]);
+
+if (diff >= 8)
+ {
+ /* MOV (element) */
+ instruction = 0x6e180400 | (data1_ind << 5) | data2_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+ if (diff > 8)
+ {
+ /* SHL */
+ instruction = 0x4f405400 | ((diff - 8) << 19) | (data2_ind << 5) | data2_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+ }
+ }
+else
+ {
+ /* MOV (element) */
+ instruction = 0x6e180400 | (data1_ind << 5) | tmp1_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+ /* SHL */
+ instruction = 0x4f405400 | (diff << 19) | (data1_ind << 5) | data2_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+ /* USHR */
+ instruction = 0x6f400400 | (diff << 19) | (tmp1_ind << 5) | tmp1_ind;
+ sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+ sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_OR | SLJIT_SIMD_REG_128, SLJIT_VR1, SLJIT_VR1, SLJIT_VR6, 0);
+ }
+
+JUMPHERE(jump[1]);
+
+OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf);
+
+for (i = 0; i < 3; i++)
+ {
+ fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);
+ fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);
+ }
+
+sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | SLJIT_SIMD_REG_128, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0);
+
+/* SHRN */
+instruction = 0x0f0c8400 | (data1_ind << 5) | data1_ind;
+sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+sljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);
+
+/* Ignore matches before the first STR_PTR. */
+OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, TMP2, 0);
+OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, TMP2, 0);
+
+jump[0] = CMP(SLJIT_NOT_ZERO, TMP1, 0, SLJIT_IMM, 0);
+
+/* Main loop. */
+start = LABEL();
+
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 16);
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128 | SLJIT_SIMD_MEM_ALIGNED_128, SLJIT_VR0, SLJIT_MEM1(STR_PTR), 0);
+sljit_emit_simd_mov(compiler, SLJIT_SIMD_REG_128, SLJIT_VR1, SLJIT_MEM1(STR_PTR), -(sljit_sw)diff);
+
+for (i = 0; i < 3; i++)
+ {
+ fast_forward_char_pair_sse2_compare(compiler, compare1_type, i, data1_ind, cmp1a_ind, cmp1b_ind, tmp1_ind);
+ fast_forward_char_pair_sse2_compare(compiler, compare2_type, i, data2_ind, cmp2a_ind, cmp2b_ind, tmp2_ind);
}
-} else {
+
+sljit_emit_simd_op2(compiler, SLJIT_SIMD_OP2_AND | SLJIT_SIMD_REG_128, SLJIT_VR0, SLJIT_VR0, SLJIT_VR1, 0);
+
+/* SHRN */
+instruction = 0x0f0c8400 | (data1_ind << 5) | data1_ind;
+sljit_emit_op_custom(compiler, &instruction, sizeof(sljit_u32));
+
+sljit_emit_simd_lane_mov(compiler, SLJIT_SIMD_STORE | SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64, SLJIT_VR0, 0, TMP1, 0);
+
+CMPTO(SLJIT_ZERO, TMP1, 0, SLJIT_IMM, 0, start);
+
+JUMPHERE(jump[0]);
+
+sljit_emit_op1(compiler, SLJIT_CTZ, TMP1, 0, TMP1, 0);
+OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);
+OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
+
+add_jump(compiler, &common->failed_match, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
+
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
- if (common->utf)
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_default_utf));
- else
-#endif
- sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_ARGS4(W, W, W, W, W),
- SLJIT_IMM, SLJIT_FUNC_ADDR(ffcps_default));
-}
+if (common->utf)
+ {
+ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-offs1));
+
+ jump[0] = jump_if_utf_char_start(compiler, TMP1);
-/* Restore STR_PTR register. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCAL0);
+ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
+ CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, restart);
-/* Check return value. */
-partial_quit = CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
-add_jump(compiler, &common->failed_match, partial_quit);
+ add_jump(compiler, &common->failed_match, JUMP(SLJIT_JUMP));
-/* Fast forward STR_PTR to the result of memchr. */
-OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
+ JUMPHERE(jump[0]);
+ }
+#endif
-JUMPHERE(partial_quit);
+OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(offs1));
+
+if (common->match_end_ptr != 0)
+ OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
}
+#undef PCRE2_REPLICATE_TYPE
+
#endif /* SLJIT_CONFIG_ARM_64 && SLJIT_CONFIG_ARM_64 */
#if (defined SLJIT_CONFIG_S390X && SLJIT_CONFIG_S390X)
@@ -1289,7 +1442,7 @@ if (char1 != char2)
#else /* PCRE2_CODE_UNIT_WIDTH == 32 */
-for (int i = 0; i < 2; i++)
+for (i = 0; i < 2; i++)
{
replicate_imm_vector(compiler, i, cmp1_ind, char1 | bit, TMP1);
@@ -1483,7 +1636,7 @@ if (char1 != char2)
#else /* PCRE2_CODE_UNIT_WIDTH == 32 */
-for (int i = 0; i < 2; i++)
+for (i = 0; i < 2; i++)
{
replicate_imm_vector(compiler, i, cmp1_ind, char1 | bit, TMP3);
@@ -1699,7 +1852,7 @@ if (char2a != char2b)
#else /* PCRE2_CODE_UNIT_WIDTH == 32 */
-for (int i = 0; i < 2; i++)
+for (i = 0; i < 2; i++)
{
replicate_imm_vector(compiler, i, cmp1a_ind, char1a | bit1, TMP1);
@@ -1865,21 +2018,18 @@ typedef sljit_ins sljit_u32;
#define IMM_UI2(imm) (((sljit_ins)(imm) << 10) & UI2_IMM_MASK)
// LSX OPCODES:
-#define VLD 0x2c000000
-#define VOR_V 0x71268000
-#define VAND_V 0x71260000
#define VBSLL_V 0x728e0000
#define VMSKLTZ_B 0x729c4000
#define VPICKVE2GR_WU 0x72f3e000
#if PCRE2_CODE_UNIT_WIDTH == 8
-#define VREPLGR2VR 0x729f0000
+#define VREPLGR2VR_X 0x729f0000
#define VSEQ 0x70000000
#elif PCRE2_CODE_UNIT_WIDTH == 16
-#define VREPLGR2VR 0x729f0400
+#define VREPLGR2VR_X 0x729f0400
#define VSEQ 0x70008000
#else
-#define VREPLGR2VR 0x729f0800
+#define VREPLGR2VR_X 0x729f0800
#define VSEQ 0x70010000
#endif
@@ -1956,14 +2106,14 @@ if (common->mode == PCRE2_JIT_COMPLETE)
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit);
/* VREPLGR2VR.B/H/W vd, rj */
-push_inst(compiler, VREPLGR2VR | VD(cmp1_ind) | RJ_V(tmp1_reg_ind));
+push_inst(compiler, VREPLGR2VR_X | VD(cmp1_ind) | RJ_V(tmp1_reg_ind));
if (char1 != char2)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2);
/* VREPLGR2VR.B/H/W vd, rj */
- push_inst(compiler, VREPLGR2VR | VD(cmp2_ind) | RJ_V(tmp1_reg_ind));
+ push_inst(compiler, VREPLGR2VR_X | VD(cmp2_ind) | RJ_V(tmp1_reg_ind));
}
OP1(SLJIT_MOV, TMP2, 0, STR_PTR, 0);
@@ -2086,14 +2236,14 @@ OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, char1 | bit);
-/* VREPLGR2VR vd, rj */
-push_inst(compiler, VREPLGR2VR | VD(cmp1_ind) | RJ_V(tmp1_reg_ind));
+/* VREPLGR2VR.B/H/W vd, rj */
+push_inst(compiler, VREPLGR2VR_X | VD(cmp1_ind) | RJ_V(tmp1_reg_ind));
if (char1 != char2)
{
OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, bit != 0 ? bit : char2);
- /* VREPLGR2VR vd, rj */
- push_inst(compiler, VREPLGR2VR | VD(cmp2_ind) | RJ_V(tmp1_reg_ind));
+ /* VREPLGR2VR.B/H/W vd, rj */
+ push_inst(compiler, VREPLGR2VR_X | VD(cmp2_ind) | RJ_V(tmp1_reg_ind));
}
OP1(SLJIT_MOV, STR_PTR, 0, TMP2, 0);
@@ -2213,13 +2363,13 @@ else
}
}
-/* VREPLGR2VR vd, rj */
-push_inst(compiler, VREPLGR2VR | VD(cmp1a_ind) | RJ_V(tmp1_reg_ind));
+/* VREPLGR2VR.B/H/W vd, rj */
+push_inst(compiler, VREPLGR2VR_X | VD(cmp1a_ind) | RJ_V(tmp1_reg_ind));
if (char1a != char1b)
{
- /* VREPLGR2VR vd, rj */
- push_inst(compiler, VREPLGR2VR | VD(cmp1b_ind) | RJ_V(tmp2_reg_ind));
+ /* VREPLGR2VR.B/H/W vd, rj */
+ push_inst(compiler, VREPLGR2VR_X | VD(cmp1b_ind) | RJ_V(tmp2_reg_ind));
}
if (char2a == char2b)
@@ -2242,13 +2392,13 @@ else
}
}
-/* VREPLGR2VR vd, rj */
-push_inst(compiler, VREPLGR2VR | VD(cmp2a_ind) | RJ_V(tmp1_reg_ind));
+/* VREPLGR2VR.B/H/W vd, rj */
+push_inst(compiler, VREPLGR2VR_X | VD(cmp2a_ind) | RJ_V(tmp1_reg_ind));
if (char2a != char2b)
{
- /* VREPLGR2VR vd, rj */
- push_inst(compiler, VREPLGR2VR | VD(cmp2b_ind) | RJ_V(tmp2_reg_ind));
+ /* VREPLGR2VR.B/H/W vd, rj */
+ push_inst(compiler, VREPLGR2VR_X | VD(cmp2b_ind) | RJ_V(tmp2_reg_ind));
}
#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
diff --git a/src/3rdparty/pcre2/src/pcre2_maketables.c b/src/3rdparty/pcre2/src/pcre2_maketables.c
index 0474cc7dbb4..0f6c5110ad0 100644
--- a/src/3rdparty/pcre2/src/pcre2_maketables.c
+++ b/src/3rdparty/pcre2/src/pcre2_maketables.c
@@ -45,13 +45,13 @@ own as part of the PCRE2 library. It is also included in the compilation of
pcre2_dftables.c as a freestanding program, in which case the macro
PCRE2_DFTABLES is defined. */
+
#ifndef PCRE2_DFTABLES /* Compiling the library */
-# ifdef HAVE_CONFIG_H
-# include "config.h"
-# endif
-# include "pcre2_internal.h"
+#include "pcre2_internal.h"
#endif
+
+
/*************************************************
* Create PCRE2 character tables *
*************************************************/
@@ -64,14 +64,15 @@ supplied, but when PCRE2_DFTABLES is defined (when compiling the pcre2_dftables
freestanding auxiliary program) malloc() is used, and the function has a
different name so as not to clash with the prototype in pcre2.h.
-Arguments: none when PCRE2_DFTABLES is defined
+Arguments: pointers to character-transforming functions when PCRE2_DFTABLES is
+ defined;
else a PCRE2 general context or NULL
-Returns: pointer to the contiguous block of data
+Returns: pointer to the contiguous block of data;
else NULL if memory allocation failed
*/
#ifdef PCRE2_DFTABLES /* Included in freestanding pcre2_dftables program */
-static const uint8_t *maketables(void)
+static const uint8_t *maketables(int (*charfn_to)(int), int (*charfn_from)(int))
{
uint8_t *yield = (uint8_t *)malloc(TABLES_LENGTH);
@@ -82,6 +83,9 @@ pcre2_maketables(pcre2_general_context *gcontext)
uint8_t *yield = (uint8_t *)((gcontext != NULL)?
gcontext->memctl.malloc(TABLES_LENGTH, gcontext->memctl.memory_data) :
malloc(TABLES_LENGTH));
+
+#define charfn_to(c) (c)
+#define charfn_from(c) (c)
#endif /* PCRE2_DFTABLES */
int i;
@@ -92,13 +96,18 @@ p = yield;
/* First comes the lower casing table */
-for (i = 0; i < 256; i++) *p++ = tolower(i);
+for (i = 0; i < 256; i++)
+ {
+ int c = charfn_from(tolower(charfn_to(i)));
+ *p++ = (c < 256)? c : i;
+ }
/* Next the case-flipping table */
for (i = 0; i < 256; i++)
{
- int c = islower(i)? toupper(i) : tolower(i);
+ int c = charfn_from(islower(charfn_to(i))? toupper(charfn_to(i))
+ : tolower(charfn_to(i)));
*p++ = (c < 256)? c : i;
}
@@ -118,17 +127,17 @@ test for alnum specially. */
memset(p, 0, cbit_length);
for (i = 0; i < 256; i++)
{
- if (isdigit(i)) p[cbit_digit + i/8] |= 1u << (i&7);
- if (isupper(i)) p[cbit_upper + i/8] |= 1u << (i&7);
- if (islower(i)) p[cbit_lower + i/8] |= 1u << (i&7);
- if (isalnum(i)) p[cbit_word + i/8] |= 1u << (i&7);
- if (i == '_') p[cbit_word + i/8] |= 1u << (i&7);
- if (isspace(i)) p[cbit_space + i/8] |= 1u << (i&7);
- if (isxdigit(i)) p[cbit_xdigit + i/8] |= 1u << (i&7);
- if (isgraph(i)) p[cbit_graph + i/8] |= 1u << (i&7);
- if (isprint(i)) p[cbit_print + i/8] |= 1u << (i&7);
- if (ispunct(i)) p[cbit_punct + i/8] |= 1u << (i&7);
- if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1u << (i&7);
+ if (isdigit(charfn_to(i))) p[cbit_digit + i/8] |= 1u << (i&7);
+ if (isupper(charfn_to(i))) p[cbit_upper + i/8] |= 1u << (i&7);
+ if (islower(charfn_to(i))) p[cbit_lower + i/8] |= 1u << (i&7);
+ if (isalnum(charfn_to(i))) p[cbit_word + i/8] |= 1u << (i&7);
+ if (i == CHAR_UNDERSCORE) p[cbit_word + i/8] |= 1u << (i&7);
+ if (isspace(charfn_to(i))) p[cbit_space + i/8] |= 1u << (i&7);
+ if (isxdigit(charfn_to(i))) p[cbit_xdigit + i/8] |= 1u << (i&7);
+ if (isgraph(charfn_to(i))) p[cbit_graph + i/8] |= 1u << (i&7);
+ if (isprint(charfn_to(i))) p[cbit_print + i/8] |= 1u << (i&7);
+ if (ispunct(charfn_to(i))) p[cbit_punct + i/8] |= 1u << (i&7);
+ if (iscntrl(charfn_to(i))) p[cbit_cntrl + i/8] |= 1u << (i&7);
}
p += cbit_length;
@@ -140,11 +149,11 @@ changed at release 8.34 and it's always been this way for PCRE2. */
for (i = 0; i < 256; i++)
{
int x = 0;
- if (isspace(i)) x += ctype_space;
- if (isalpha(i)) x += ctype_letter;
- if (islower(i)) x += ctype_lcletter;
- if (isdigit(i)) x += ctype_digit;
- if (isalnum(i) || i == '_') x += ctype_word;
+ if (isspace(charfn_to(i))) x += ctype_space;
+ if (isalpha(charfn_to(i))) x += ctype_letter;
+ if (islower(charfn_to(i))) x += ctype_lcletter;
+ if (isdigit(charfn_to(i))) x += ctype_digit;
+ if (isalnum(charfn_to(i)) || i == CHAR_UNDERSCORE) x += ctype_word;
*p++ = x;
}
@@ -152,6 +161,9 @@ return yield;
}
#ifndef PCRE2_DFTABLES /* Compiling the library */
+#undef charfn_to
+#undef charfn_from
+
PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION
pcre2_maketables_free(pcre2_general_context *gcontext, const uint8_t *tables)
{
diff --git a/src/3rdparty/pcre2/src/pcre2_match.c b/src/3rdparty/pcre2/src/pcre2_match.c
index 34a92eaa36e..d5574d721a2 100644
--- a/src/3rdparty/pcre2/src/pcre2_match.c
+++ b/src/3rdparty/pcre2/src/pcre2_match.c
@@ -39,12 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
+
+
/* These defines enable debugging code */
/* #define DEBUG_FRAMES_DISPLAY */
@@ -367,6 +365,10 @@ PCRE2_SIZE length;
PCRE2_SPTR eptr;
PCRE2_SPTR eptr_start;
+#ifndef SUPPORT_UNICODE
+(void)caseopts; /* Avoid compiler warning. */
+#endif
+
/* Deal with an unset group. The default is no match, but there is an option to
match an empty string. */
@@ -385,6 +387,7 @@ if (offset >= Foffset_top || Fovector[offset] == PCRE2_UNSET)
eptr = eptr_start = Feptr;
p = mb->start_subject + Fovector[offset];
length = Fovector[offset+1] - Fovector[offset];
+PCRE2_ASSERT(eptr <= mb->end_subject);
if (caseless)
{
@@ -404,7 +407,7 @@ if (caseless)
bytes in UTF-8); a sequence of 3 of the former uses 6 bytes, as does a
sequence of two of the latter. It is important, therefore, to check the
length along the reference, not along the subject (earlier code did this
- wrong). UCP without uses Unicode properties but without UTF encoding. */
+ wrong). UCP uses Unicode properties but without UTF encoding. */
while (p < endptr)
{
@@ -483,8 +486,8 @@ else
else
{
- if ((PCRE2_SIZE)(mb->end_subject - eptr) < length) return 1; /* Partial */
- if (memcmp(p, eptr, CU2BYTES(length)) != 0) return -1; /* No match */
+ if ((PCRE2_SIZE)(mb->end_subject - eptr) < length ||
+ memcmp(p, eptr, CU2BYTES(length)) != 0) return -1; /* No match */
eptr += length;
}
}
@@ -495,6 +498,75 @@ return 0; /* Match */
+/*************************************************
+* Restore offsets after a recurse *
+*************************************************/
+
+/* This function restores the ovector values when
+a recursive block reaches its end, and the triggering
+recurse has and argument list.
+
+Arguments:
+ F the current backtracking frame pointer
+ P the previous backtracking frame pointer
+*/
+
+static void
+recurse_update_offsets(heapframe *F, heapframe *P)
+{
+PCRE2_SIZE *dst = F->ovector;
+PCRE2_SIZE *src = P->ovector;
+/* The first bracket has offset 2, because
+offset 0 is reserved for the full match. */
+PCRE2_SIZE offset = 2;
+PCRE2_SIZE offset_top = Foffset_top + 2;
+PCRE2_SIZE diff;
+PCRE2_SPTR ecode = Fecode;
+
+do
+ {
+ diff = (GET2(ecode, 1) << 1) - offset;
+ ecode += 1 + IMM2_SIZE;
+
+ if (offset + diff >= offset_top)
+ {
+ /* Some OP_CREF opcodes are not
+ processed, they must be skipped. */
+ while (*ecode == OP_CREF) ecode += 1 + IMM2_SIZE;
+ break;
+ }
+
+ if (diff == 2)
+ {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ }
+ else if (diff >= 4)
+ memcpy(dst, src, diff * sizeof(PCRE2_SIZE));
+
+ /* Skip the unmodified entry. */
+ diff += 2;
+ offset += diff;
+ dst += diff;
+ src += diff;
+ }
+while (*ecode == OP_CREF);
+
+diff = offset_top - offset;
+if (diff == 2)
+ {
+ dst[0] = src[0];
+ dst[1] = src[1];
+ }
+else if (diff >= 4)
+ memcpy(dst, src, diff * sizeof(PCRE2_SIZE));
+
+Fecode = ecode;
+Foffset_top = (offset <= P->offset_top) ? P->offset_top : (offset - 2);
+}
+
+
+
/******************************************************************************
*******************************************************************************
"Recursion" in the match() function
@@ -898,7 +970,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
Fecode += 1 + LINK_SIZE;
continue;
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* OP_END itself can never be reached within a recursion because that is
picked up when the OP_KET that always precedes OP_END is reached. */
@@ -938,11 +1010,28 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
}
#ifdef DEBUG_SHOW_OPS
- fprintf(stderr, "++ Failed ACCEPT not at end (endanchnored set)\n");
+ fprintf(stderr, "++ Failed ACCEPT not at end (endanchored set)\n");
#endif
return MATCH_NOMATCH; /* (*ACCEPT) */
}
+ /* Fail if we detect that the start position was moved to be either after
+ the end position (\K in lookahead) or before the start offset (\K in
+ lookbehind). If this occurs, the pattern must have used \K in a somewhat
+ sneaky way (e.g. by pattern recursion), because if the \K is actually
+ syntactically inside the lookaround, it's blocked at compile-time. */
+
+ if (Fstart_match < mb->start_subject + mb->start_offset ||
+ Fstart_match > Feptr)
+ {
+ /* The \K expression is fairly rare. We assert it was used so that we
+ catch any unexpected invalid data in start_match. */
+ PCRE2_ASSERT(mb->hasbsk);
+
+ if (!mb->allowlookaroundbsk)
+ return PCRE2_ERROR_BAD_BACKSLASH_K;
+ }
+
/* We have a successful match of the whole pattern. Record the result and
then do a direct return from the function. If there is space in the offset
vector, set any pairs that follow the highest-numbered captured string but
@@ -982,7 +1071,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
mb->hitend = TRUE;
if (mb->partial > 1) return PCRE2_ERROR_PARTIAL;
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* Match any single character whatsoever. */
@@ -2779,9 +2868,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
/* This should never occur */
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
Fecode += 3;
@@ -3130,9 +3221,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
/* This should not occur */
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
}
@@ -3406,9 +3499,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
}
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
} /* End switch(Lctype) */
else
@@ -3659,9 +3754,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
}
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
}
@@ -3945,9 +4042,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
PCRE2_UNREACHABLE(); /* Control never reaches here */
/* This should never occur */
+
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
}
@@ -4100,9 +4200,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
RRETURN(MATCH_NOMATCH);
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
}
}
@@ -4245,9 +4347,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
RRETURN(MATCH_NOMATCH);
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
}
}
@@ -4514,9 +4618,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
}
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
/* Feptr is now past the end of the maximum run */
@@ -4833,9 +4939,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
}
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
if (reptype == REPTYPE_POS) continue; /* No backtracking */
@@ -5091,9 +5199,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
}
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
if (reptype == REPTYPE_POS) continue; /* No backtracking */
@@ -5990,7 +6100,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
assert_accept_frame->offset_top * sizeof(PCRE2_SIZE));
Foffset_top = assert_accept_frame->offset_top;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* In the case of a match, the captures have already been put into
the current frame. */
@@ -6263,12 +6373,18 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
/* Reinstate the previous set of captures and then carry on after the
recursion call. */
- memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
- Foffset_top * sizeof(PCRE2_SIZE));
- Foffset_top = P->offset_top;
+ Fecode = P->ecode + 1 + LINK_SIZE;
+
+ if (*Fecode != OP_CREF)
+ {
+ memcpy(F->ovector, P->ovector, Foffset_top * sizeof(PCRE2_SIZE));
+ Foffset_top = P->offset_top;
+ }
+ else
+ recurse_update_offsets(F, P);
+
Fcapture_last = P->capture_last;
Fcurrent_recurse = P->current_recurse;
- Fecode = P->ecode + 1 + LINK_SIZE;
continue; /* With next opcode */
case OP_COND: /* No need to do anything for these */
@@ -6282,7 +6398,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
case OP_ASSERTBACK_NA:
if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
RRETURN(MATCH_NOMATCH);
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_ASSERT_NA:
if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
@@ -6296,12 +6412,12 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
case OP_ASSERTBACK:
if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
RRETURN(MATCH_NOMATCH);
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_ASSERT:
if (Feptr > mb->last_used_ptr) mb->last_used_ptr = Feptr;
Feptr = P->eptr;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* For an atomic group, discard internal backtracking points. We must
also ensure that any remaining branches within the top-level of the group
@@ -6325,7 +6441,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
case OP_ASSERTBACK_NOT:
if (branch_start[1 + LINK_SIZE] == OP_VREVERSE && Feptr != P->eptr)
RRETURN(MATCH_NOMATCH);
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_ASSERT_NOT:
RRETURN(MATCH_MATCH);
@@ -6370,12 +6486,18 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
if (Fcurrent_recurse == number)
{
P = (heapframe *)((char *)N - frame_size);
- memcpy((char *)F + offsetof(heapframe, ovector), P->ovector,
- Foffset_top * sizeof(PCRE2_SIZE));
- Foffset_top = P->offset_top;
+ Fecode = P->ecode + 1 + LINK_SIZE;
+
+ if (*Fecode != OP_CREF)
+ {
+ memcpy(F->ovector, P->ovector, Foffset_top * sizeof(PCRE2_SIZE));
+ Foffset_top = P->offset_top;
+ }
+ else
+ recurse_update_offsets(F, P);
+
Fcapture_last = P->capture_last;
Fcurrent_recurse = P->current_recurse;
- Fecode = P->ecode + 1 + LINK_SIZE;
continue; /* With next opcode */
}
@@ -6453,7 +6575,7 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
if ((mb->moptions & PCRE2_NOTEOL) != 0) RRETURN(MATCH_NOMATCH);
if ((mb->poptions & PCRE2_DOLLAR_ENDONLY) == 0) goto ASSERT_NL_OR_EOS;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* Unconditional end of subject assertion (\z). */
case OP_EOD:
@@ -6751,9 +6873,11 @@ fprintf(stderr, "++ %2ld op=%3d %s\n", Fecode - mb->start_code, *Fecode,
/* There's been some horrible disaster. Arrival here can only mean there is
something seriously wrong in the code above or the OP_xxx definitions. */
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
/* Do not insert any code in here without much thought; it is assumed
@@ -6801,9 +6925,11 @@ switch (Freturn_id)
LBL(221) LBL(222) LBL(223) LBL(224)
#endif
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
#undef LBL
}
@@ -6839,9 +6965,9 @@ pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length,
pcre2_match_context *mcontext)
{
int rc;
-int was_zero_terminated = 0;
const uint8_t *start_bits = NULL;
const pcre2_real_code *re = (const pcre2_real_code *)code;
+uint32_t original_options = options;
BOOL anchored;
BOOL firstline;
@@ -6859,6 +6985,8 @@ PCRE2_UCHAR first_cu2 = 0;
PCRE2_UCHAR req_cu = 0;
PCRE2_UCHAR req_cu2 = 0;
+PCRE2_UCHAR null_str[1] = { 0xcd };
+PCRE2_SPTR original_subject = subject;
PCRE2_SPTR bumpalong_limit;
PCRE2_SPTR end_subject;
PCRE2_SPTR true_end_subject;
@@ -6897,33 +7025,35 @@ match_block *mb = &actual_match_block;
/* Recognize NULL, length 0 as an empty string. */
-if (subject == NULL && length == 0) subject = (PCRE2_SPTR)"";
+if (subject == NULL && length == 0) subject = null_str;
/* Plausibility checks */
-if ((options & ~PUBLIC_MATCH_OPTIONS) != 0) return PCRE2_ERROR_BADOPTION;
-if (code == NULL || subject == NULL || match_data == NULL)
- return PCRE2_ERROR_NULL;
+if (match_data == NULL) return PCRE2_ERROR_NULL;
+if (code == NULL || subject == NULL)
+ return match_data->rc = PCRE2_ERROR_NULL;
+if ((options & ~PUBLIC_MATCH_OPTIONS) != 0)
+ return match_data->rc = PCRE2_ERROR_BADOPTION;
start_match = subject + start_offset;
req_cu_ptr = start_match - 1;
if (length == PCRE2_ZERO_TERMINATED)
{
length = PRIV(strlen)(subject);
- was_zero_terminated = 1;
}
true_end_subject = end_subject = subject + length;
-if (start_offset > length) return PCRE2_ERROR_BADOFFSET;
+if (start_offset > length) return match_data->rc = PCRE2_ERROR_BADOFFSET;
/* Check that the first field in the block is the magic number. */
-if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
+if (re->magic_number != MAGIC_NUMBER)
+ return match_data->rc = PCRE2_ERROR_BADMAGIC;
/* Check the code unit width. */
if ((re->flags & PCRE2_MODE_MASK) != PCRE2_CODE_UNIT_WIDTH/8)
- return PCRE2_ERROR_BADMODE;
+ return match_data->rc = PCRE2_ERROR_BADMODE;
/* PCRE2_NOTEMPTY and PCRE2_NOTEMPTY_ATSTART are match-time flags in the
options variable for this function. Users of PCRE2 who are not calling the
@@ -6970,17 +7100,18 @@ time. */
if (mb->partial != 0 &&
((re->overall_options | options) & PCRE2_ENDANCHORED) != 0)
- return PCRE2_ERROR_BADOPTION;
+ return match_data->rc = PCRE2_ERROR_BADOPTION;
/* It is an error to set an offset limit without setting the flag at compile
time. */
if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET &&
(re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0)
- return PCRE2_ERROR_BADOFFSETLIMIT;
+ return match_data->rc = PCRE2_ERROR_BADOFFSETLIMIT;
/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT,
-free the memory that was obtained. Set the field to NULL for no match cases. */
+free the memory that was obtained. Set the field to NULL for match error
+cases. */
if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0)
{
@@ -7017,11 +7148,11 @@ if (use_jit)
#if PCRE2_CODE_UNIT_WIDTH != 32
if (start_match < end_subject && NOT_FIRSTCU(*start_match))
{
- if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
+ if (start_offset > 0) return match_data->rc = PCRE2_ERROR_BADUTFOFFSET;
#if PCRE2_CODE_UNIT_WIDTH == 8
- return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
+ return match_data->rc = PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
#else
- return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
+ return match_data->rc = PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
#endif
}
#endif /* WIDTH != 32 */
@@ -7056,12 +7187,12 @@ if (use_jit)
/* Validate the relevant portion of the subject. Adjust the offset of an
invalid code point to be an absolute offset in the whole string. */
- match_data->rc = PRIV(valid_utf)(start_match,
+ rc = PRIV(valid_utf)(start_match,
length - (start_match - subject), &(match_data->startchar));
- if (match_data->rc != 0)
+ if (rc != 0)
{
match_data->startchar += start_match - subject;
- return match_data->rc;
+ return match_data->rc = rc;
}
jit_checked_utf = TRUE;
}
@@ -7074,16 +7205,27 @@ if (use_jit)
match_data, mcontext);
if (rc != PCRE2_ERROR_JIT_BADOPTION)
{
- match_data->subject_length = length;
+ match_data->options = original_options;
if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
{
- length = CU2BYTES(length + was_zero_terminated);
- match_data->subject = match_data->memctl.malloc(length,
- match_data->memctl.memory_data);
- if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy((void *)match_data->subject, subject, length);
+ if (length != 0)
+ {
+ match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
+ match_data->memctl.memory_data);
+ if (match_data->subject == NULL)
+ return match_data->rc = PCRE2_ERROR_NOMEMORY;
+ memcpy((void *)match_data->subject, subject, CU2BYTES(length));
+ }
+ else
+ match_data->subject = NULL;
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
}
+ else
+ {
+ /* When pcre2_jit_match sets the subject, it doesn't know what the
+ original passed-in pointer was. */
+ if (match_data->subject != NULL) match_data->subject = original_subject;
+ }
return rc;
}
}
@@ -7140,11 +7282,11 @@ if (utf &&
}
else if (start_match < end_subject && NOT_FIRSTCU(*start_match))
{
- if (start_offset > 0) return PCRE2_ERROR_BADUTFOFFSET;
+ if (start_offset > 0) return match_data->rc = PCRE2_ERROR_BADUTFOFFSET;
#if PCRE2_CODE_UNIT_WIDTH == 8
- return PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
+ return match_data->rc = PCRE2_ERROR_UTF8_ERR20; /* Isolated 0x80 byte */
#else
- return PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
+ return match_data->rc = PCRE2_ERROR_UTF16_ERR3; /* Isolated low surrogate */
#endif
}
#endif /* WIDTH != 32 */
@@ -7192,10 +7334,10 @@ if (utf &&
for (;;)
{
- match_data->rc = PRIV(valid_utf)(mb->check_subject,
+ rc = PRIV(valid_utf)(mb->check_subject,
length - (mb->check_subject - subject), &(match_data->startchar));
- if (match_data->rc == 0) break; /* Valid UTF string */
+ if (rc == 0) break; /* Valid UTF string */
/* Invalid UTF string. Adjust the offset to be an absolute offset in the
whole string. If we are handling invalid UTF strings, set end_subject to
@@ -7203,7 +7345,7 @@ if (utf &&
Otherwise return the error. */
match_data->startchar += mb->check_subject - subject;
- if (!allow_invalid || match_data->rc > 0) return match_data->rc;
+ if (!allow_invalid || rc > 0) return match_data->rc = rc;
end_subject = subject + match_data->startchar;
/* If the end precedes start_match, it means there is invalid UTF in the
@@ -7268,8 +7410,11 @@ mb->start_offset = start_offset;
mb->end_subject = end_subject;
mb->true_end_subject = true_end_subject;
mb->hasthen = (re->flags & PCRE2_HASTHEN) != 0;
+mb->hasbsk = (re->flags & PCRE2_HASBSK) != 0;
mb->allowemptypartial = (re->max_lookbehind > 0) ||
(re->flags & PCRE2_MATCH_EMPTY) != 0;
+mb->allowlookaroundbsk =
+ (re->extra_options & PCRE2_EXTRA_ALLOW_LOOKAROUND_BSK) != 0;
mb->poptions = re->overall_options; /* Pattern options */
mb->ignore_skip_arg = 0;
mb->mark = mb->nomatch_mark = NULL; /* In case never set */
@@ -7317,9 +7462,11 @@ switch(re->newline_convention)
mb->nltype = NLTYPE_ANYCRLF;
break;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
- return PCRE2_ERROR_INTERNAL;
+ return match_data->rc = PCRE2_ERROR_INTERNAL;
+ /* LCOV_EXCL_STOP */
}
/* The backtracking frames have fixed data at the front, and a PCRE2_SIZE
@@ -7361,7 +7508,7 @@ if (heapframes_size < START_FRAMES_SIZE) heapframes_size = START_FRAMES_SIZE;
if (heapframes_size / 1024 > mb->heap_limit)
{
PCRE2_SIZE max_size = 1024 * mb->heap_limit;
- if (max_size < frame_size) return PCRE2_ERROR_HEAPLIMIT;
+ if (max_size < frame_size) return match_data->rc = PCRE2_ERROR_HEAPLIMIT;
heapframes_size = max_size;
}
@@ -7377,7 +7524,7 @@ if (match_data->heapframes_size < heapframes_size)
if (match_data->heapframes == NULL)
{
match_data->heapframes_size = 0;
- return PCRE2_ERROR_NOMEMORY;
+ return match_data->rc = PCRE2_ERROR_NOMEMORY;
}
match_data->heapframes_size = heapframes_size;
}
@@ -7853,7 +8000,7 @@ for(;;)
new_start_match = mb->verb_skip_ptr;
break;
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* NOMATCH and PRUNE advance by one character. THEN at this level acts
exactly like PRUNE. Unset ignore SKIP-with-argument. */
@@ -8011,6 +8158,7 @@ if (utf && end_subject != true_end_subject &&
match_data->code = re;
match_data->mark = mb->mark;
match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER;
+match_data->options = original_options;
/* Handle a fully successful match. Set the return code to the number of
captured strings, or 0 if there were too many to fit into the ovector, and then
@@ -8022,20 +8170,26 @@ if (rc == MATCH_MATCH)
match_data->rc = ((int)mb->end_offset_top >= 2 * match_data->oveccount)?
0 : (int)mb->end_offset_top/2 + 1;
match_data->subject_length = length;
+ match_data->start_offset = start_offset;
match_data->startchar = start_match - subject;
match_data->leftchar = mb->start_used_ptr - subject;
match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)?
mb->last_used_ptr : mb->end_match_ptr) - subject;
if ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0)
{
- length = CU2BYTES(length + was_zero_terminated);
- match_data->subject = match_data->memctl.malloc(length,
- match_data->memctl.memory_data);
- if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY;
- memcpy((void *)match_data->subject, subject, length);
+ if (length != 0)
+ {
+ match_data->subject = match_data->memctl.malloc(CU2BYTES(length),
+ match_data->memctl.memory_data);
+ if (match_data->subject == NULL)
+ return match_data->rc = PCRE2_ERROR_NOMEMORY;
+ memcpy((void *)match_data->subject, subject, CU2BYTES(length));
+ }
+ else
+ match_data->subject = NULL;
match_data->flags |= PCRE2_MD_COPIED_SUBJECT;
}
- else match_data->subject = subject;
+ else match_data->subject = original_subject;
return match_data->rc;
}
@@ -8057,8 +8211,9 @@ PCRE2_ERROR_PARTIAL. */
else if (match_partial != NULL)
{
- match_data->subject = subject;
+ match_data->subject = original_subject;
match_data->subject_length = length;
+ match_data->start_offset = start_offset;
match_data->ovector[0] = match_partial - subject;
match_data->ovector[1] = end_subject - subject;
match_data->startchar = match_partial - subject;
@@ -8069,7 +8224,13 @@ else if (match_partial != NULL)
/* Else this is the classic nomatch case. */
-else match_data->rc = PCRE2_ERROR_NOMATCH;
+else
+ {
+ match_data->subject = original_subject;
+ match_data->subject_length = length;
+ match_data->start_offset = start_offset;
+ match_data->rc = PCRE2_ERROR_NOMATCH;
+ }
return match_data->rc;
}
diff --git a/src/3rdparty/pcre2/src/pcre2_match_data.c b/src/3rdparty/pcre2/src/pcre2_match_data.c
index 100e7c9d944..fade67ae522 100644
--- a/src/3rdparty/pcre2/src/pcre2_match_data.c
+++ b/src/3rdparty/pcre2/src/pcre2_match_data.c
@@ -39,10 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
@@ -85,6 +81,7 @@ PCRE2_EXP_DEFN pcre2_match_data * PCRE2_CALL_CONVENTION
pcre2_match_data_create_from_pattern(const pcre2_code *code,
pcre2_general_context *gcontext)
{
+if (code == NULL) return NULL;
if (gcontext == NULL) gcontext = (pcre2_general_context *)code;
return pcre2_match_data_create(((const pcre2_real_code *)code)->top_bracket + 1,
gcontext);
diff --git a/src/3rdparty/pcre2/src/pcre2_newline.c b/src/3rdparty/pcre2/src/pcre2_newline.c
index 6e9366db93c..a7c929921ea 100644
--- a/src/3rdparty/pcre2/src/pcre2_newline.c
+++ b/src/3rdparty/pcre2/src/pcre2_newline.c
@@ -48,10 +48,6 @@ and NLTYPE_ANY. The full list of Unicode newline characters is taken from
http://unicode.org/unicode/reports/tr18/. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
diff --git a/src/3rdparty/pcre2/src/pcre2_ord2utf.c b/src/3rdparty/pcre2/src/pcre2_ord2utf.c
index a1e9e08803b..3b8aead7595 100644
--- a/src/3rdparty/pcre2/src/pcre2_ord2utf.c
+++ b/src/3rdparty/pcre2/src/pcre2_ord2utf.c
@@ -43,13 +43,10 @@ POSSIBILITY OF SUCH DAMAGE.
into a UTF string. The behaviour is different for each code unit width. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
+
/* If SUPPORT_UNICODE is not defined, this function will never be called.
Supply a dummy function because some compilers do not like empty source
modules. */
@@ -83,16 +80,17 @@ PRIV(ord2utf)(uint32_t cvalue, PCRE2_UCHAR *buffer)
/* Convert to UTF-8 */
#if PCRE2_CODE_UNIT_WIDTH == 8
-int i, j;
+unsigned int i;
+
for (i = 0; i < PRIV(utf8_table1_size); i++)
if ((int)cvalue <= PRIV(utf8_table1)[i]) break;
buffer += i;
-for (j = i; j > 0; j--)
+for (unsigned int j = i; j != 0; j--)
{
*buffer-- = 0x80 | (cvalue & 0x3f);
cvalue >>= 6;
}
-*buffer = PRIV(utf8_table2)[i] | cvalue;
+*buffer = (PCRE2_UCHAR)(PRIV(utf8_table2)[i] | (int)cvalue);
return i + 1;
/* Convert to UTF-16 */
diff --git a/src/3rdparty/pcre2/src/pcre2_pattern_info.c b/src/3rdparty/pcre2/src/pcre2_pattern_info.c
index fe4d3c661a0..e0bd83a90e0 100644
--- a/src/3rdparty/pcre2/src/pcre2_pattern_info.c
+++ b/src/3rdparty/pcre2/src/pcre2_pattern_info.c
@@ -39,13 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
+
/*************************************************
* Return info about compiled pattern *
*************************************************/
@@ -292,8 +289,7 @@ if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
cb.version = 0;
-cc = (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code))
- + re->name_count * re->name_entry_size;
+cc = (PCRE2_SPTR)((uint8_t *)re + re->code_start);
while (TRUE)
{
diff --git a/src/3rdparty/pcre2/src/pcre2_script_run.c b/src/3rdparty/pcre2/src/pcre2_script_run.c
index 4926fa63bbf..acdf41fe668 100644
--- a/src/3rdparty/pcre2/src/pcre2_script_run.c
+++ b/src/3rdparty/pcre2/src/pcre2_script_run.c
@@ -38,15 +38,14 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains the function for checking a script run. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include "pcre2_internal.h"
+
/*************************************************
* Check script run *
*************************************************/
diff --git a/src/3rdparty/pcre2/src/pcre2_serialize.c b/src/3rdparty/pcre2/src/pcre2_serialize.c
index a10e3020bbe..f10a3fa0ddd 100644
--- a/src/3rdparty/pcre2/src/pcre2_serialize.c
+++ b/src/3rdparty/pcre2/src/pcre2_serialize.c
@@ -38,16 +38,14 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains functions for serializing and deserializing
a sequence of compiled codes. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "pcre2_internal.h"
-#include "pcre2_internal.h"
/* Magic number to provide a small check against being handed junk. */
diff --git a/src/3rdparty/pcre2/src/pcre2_string_utils.c b/src/3rdparty/pcre2/src/pcre2_string_utils.c
index ebfa9434e39..f1ac718f6bd 100644
--- a/src/3rdparty/pcre2/src/pcre2_string_utils.c
+++ b/src/3rdparty/pcre2/src/pcre2_string_utils.c
@@ -38,53 +38,15 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains internal functions for comparing and finding the length
of strings. These are used instead of strcmp() etc because the standard
functions work only on 8-bit data. */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
-/*************************************************
-* Emulated memmove() for systems without it *
-*************************************************/
-
-/* This function can make use of bcopy() if it is available. Otherwise do it by
-steam, as there some non-Unix environments that lack both memmove() and
-bcopy(). */
-
-#if !defined(VPCOMPAT) && !defined(HAVE_MEMMOVE)
-void *
-PRIV(memmove)(void *d, const void *s, size_t n)
-{
-#ifdef HAVE_BCOPY
-bcopy(s, d, n);
-return d;
-#else
-size_t i;
-unsigned char *dest = (unsigned char *)d;
-const unsigned char *src = (const unsigned char *)s;
-if (dest > src)
- {
- dest += n;
- src += n;
- for (i = 0; i < n; ++i) *(--dest) = *(--src);
- return (void *)dest;
- }
-else
- {
- for (i = 0; i < n; ++i) *dest++ = *src++;
- return (void *)(dest - n);
- }
-#endif /* not HAVE_BCOPY */
-}
-#endif /* not VPCOMPAT && not HAVE_MEMMOVE */
-
/*************************************************
* Compare two zero-terminated PCRE2 strings *
diff --git a/src/3rdparty/pcre2/src/pcre2_study.c b/src/3rdparty/pcre2/src/pcre2_study.c
index 85764cea565..9f7fd6bd6b0 100644
--- a/src/3rdparty/pcre2/src/pcre2_study.c
+++ b/src/3rdparty/pcre2/src/pcre2_study.c
@@ -38,16 +38,15 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains functions for scanning a compiled pattern and
collecting data (e.g. minimum matching length). */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
+
+
/* The maximum remembered capturing brackets minimum. */
#define MAX_CACHE_BACKREF 128
@@ -139,7 +138,7 @@ for (;;)
PCRE2_UCHAR op;
PCRE2_SPTR cs, ce;
- if (branchlength >= UINT16_MAX)
+ if (branchlength >= (int)UINT16_MAX)
{
branchlength = UINT16_MAX;
cc = nextbranch;
@@ -176,7 +175,7 @@ for (;;)
cc += 1 + LINK_SIZE;
break;
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_ONCE:
case OP_SCRIPT_RUN:
@@ -253,7 +252,7 @@ for (;;)
case OP_ASSERT_SCS:
case OP_ASSERTBACK_NA:
do cc += GET(cc, 1); while (*cc == OP_ALT);
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* Skip over things that don't match chars */
@@ -353,7 +352,7 @@ for (;;)
case OP_PROP:
case OP_NOTPROP:
cc += 2;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_NOT_DIGIT:
case OP_DIGIT:
@@ -434,7 +433,7 @@ for (;;)
case OP_CRMINPLUS:
case OP_CRPOSPLUS:
branchlength++;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CRSTAR:
case OP_CRMINSTAR:
@@ -628,11 +627,11 @@ for (;;)
break;
}
- /* Take care not to overflow: (1) min and d are ints, so check that their
- product is not greater than INT_MAX. (2) branchlength is limited to
- UINT16_MAX (checked at the top of the loop). */
+ /* Take care not to overflow: (1) min and d are ints, so check that their
+ product is not greater than INT_MAX. (2) branchlength is limited to
+ UINT16_MAX (checked at the top of the loop). */
- if ((d > 0 && (INT_MAX/d) < min) || UINT16_MAX - branchlength < min*d)
+ if ((d > 0 && (INT_MAX/d) < min) || (int)UINT16_MAX - branchlength < min*d)
branchlength = UINT16_MAX;
else branchlength += min * d;
break;
@@ -753,14 +752,18 @@ for (;;)
/* This should not occur: we list all opcodes explicitly so that when
new ones get added they are properly considered. */
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return -3;
+ /* LCOV_EXCL_STOP */
}
}
+/* LCOV_EXCL_START */
PCRE2_DEBUG_UNREACHABLE(); /* Control should never reach here */
return -3; /* Avoid compiler warnings */
+/* LCOV_EXCL_STOP */
}
@@ -1304,7 +1307,7 @@ do
case OP_PROP:
if (ncode[1] != PT_CLIST) break;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_ANYNL:
case OP_CHAR:
case OP_CHARI:
@@ -1328,7 +1331,7 @@ do
tcode = ncode;
continue; /* With the following significant opcode */
}
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* For a group bracket or a positive assertion without an immediately
following mandatory setting, recurse to set bits from within the
@@ -1456,7 +1459,7 @@ do
case OP_EXACT:
tcode += IMM2_SIZE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CHAR:
case OP_PLUS:
case OP_MINPLUS:
@@ -1467,7 +1470,7 @@ do
case OP_EXACTI:
tcode += IMM2_SIZE;
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_CHARI:
case OP_PLUSI:
case OP_MINPLUSI:
@@ -1487,10 +1490,10 @@ do
SET_BIT(CHAR_SPACE);
/* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
- the bits for 0xA0 and for code units >= 255, independently of UTF. */
+ the bits for NBSP and for code units >= 255, independently of UTF. */
#if PCRE2_CODE_UNIT_WIDTH != 8
- SET_BIT(0xA0);
+ SET_BIT(CHAR_NBSP);
SET_BIT(0xFF);
#else
/* For the 8-bit library in UTF-8 mode, set the bits for the first code
@@ -1506,12 +1509,9 @@ do
}
else
#endif
- /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless
- the code is EBCDIC. */
+ /* For the 8-bit library not in UTF-8 mode, set the bit for NBSP. */
{
-#ifndef EBCDIC
- SET_BIT(0xA0);
-#endif /* Not EBCDIC */
+ SET_BIT(CHAR_NBSP);
}
#endif /* 8-bit support */
@@ -1606,7 +1606,8 @@ do
case OP_TYPEUPTO:
case OP_TYPEMINUPTO:
case OP_TYPEPOSUPTO:
- tcode += IMM2_SIZE; /* Fall through */
+ tcode += IMM2_SIZE;
+ PCRE2_FALLTHROUGH /* Fall through */
case OP_TYPESTAR:
case OP_TYPEMINSTAR:
@@ -1626,10 +1627,10 @@ do
SET_BIT(CHAR_SPACE);
/* For the 16-bit and 32-bit libraries (which can never be EBCDIC), set
- the bits for 0xA0 and for code units >= 255, independently of UTF. */
+ the bits for NBSP and for code units >= 255, independently of UTF. */
#if PCRE2_CODE_UNIT_WIDTH != 8
- SET_BIT(0xA0);
+ SET_BIT(CHAR_NBSP);
SET_BIT(0xFF);
#else
/* For the 8-bit library in UTF-8 mode, set the bits for the first code
@@ -1645,12 +1646,9 @@ do
}
else
#endif
- /* For the 8-bit library not in UTF-8 mode, set the bit for 0xA0, unless
- the code is EBCDIC. */
+ /* For the 8-bit library not in UTF-8 mode, set the bit for NBSP. */
{
-#ifndef EBCDIC
- SET_BIT(0xA0);
-#endif /* Not EBCDIC */
+ SET_BIT(CHAR_NBSP);
}
#endif /* 8-bit support */
break;
@@ -1779,9 +1777,11 @@ do
case XCL_END:
goto HANDLE_CLASSMAP;
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return SSB_UNKNOWN; /* Internal error, should not occur */
+ /* LCOV_EXCL_STOP */
}
}
#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */
@@ -1790,7 +1790,7 @@ do
/* It seems that the fall through comment must be outside the #ifdef if
it is to avoid the gcc compiler warning. */
- /* Fall through */
+ PCRE2_FALLTHROUGH /* Fall through */
/* Enter here for a negative non-XCLASS. In the 8-bit library, if we are
in UTF mode, any byte with a value >= 0xc4 is a potentially valid starter
@@ -1805,14 +1805,15 @@ do
re->start_bitmap[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */
memset(re->start_bitmap+25, 0xff, 7); /* Bits for 0xc9 - 0xff */
}
+ PCRE2_FALLTHROUGH /* Fall through */
#elif PCRE2_CODE_UNIT_WIDTH != 8
SET_BIT(0xFF); /* For characters >= 255 */
+ PCRE2_FALLTHROUGH /* Fall through */
#endif
- /* Fall through */
/* Enter here for a positive non-XCLASS. If we have fallen through from
an XCLASS, classmap will already be set; just advance the code pointer.
- Otherwise, set up classmap for a a non-XCLASS and advance past it. */
+ Otherwise, set up classmap for a non-XCLASS and advance past it. */
case OP_CLASS:
if (*tcode == OP_XCLASS) tcode += GET(tcode, 1); else
@@ -1930,11 +1931,13 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
{
int depth = 0;
int rc = set_start_bits(re, code, utf, ucp, &depth);
+ /* LCOV_EXCL_START */
if (rc == SSB_UNKNOWN)
{
PCRE2_DEBUG_UNREACHABLE();
return 1;
}
+ /* LCOV_EXCL_STOP */
/* If a list of starting code units was set up, scan the list to see if only
one or two were listed. Having only one listed is rare because usually a
@@ -2002,6 +2005,16 @@ if ((re->flags & (PCRE2_FIRSTSET|PCRE2_STARTLINE)) == 0)
if (d != a) goto DONE; /* Not the other case of a */
b = c; /* Save second in b */
+
+#ifdef EBCDIC
+ /* To match ASCII (which puts the uppercase one in a), swap a & b
+ if needed. This doesn't really matter, but neatens the tests. */
+ if (TABLE_GET((unsigned int)a, re->tables + lcc_offset, a) == a)
+ {
+ b = a;
+ a = c;
+ }
+#endif
}
else goto DONE; /* More than two characters found */
}
@@ -2049,16 +2062,20 @@ if ((re->flags & (PCRE2_MATCH_EMPTY|PCRE2_HASACCEPT)) == 0 &&
case -1: /* \C in UTF mode or over-complex regex */
break; /* Leave minlength unchanged (will be zero) */
+ /* LCOV_EXCL_START */
case -2:
PCRE2_DEBUG_UNREACHABLE();
return 2; /* missing capturing bracket */
+ /* LCOV_EXCL_STOP */
+ /* LCOV_EXCL_START */
case -3:
PCRE2_DEBUG_UNREACHABLE();
return 3; /* unrecognized opcode */
+ /* LCOV_EXCL_STOP */
default:
- re->minlength = (min > UINT16_MAX)? UINT16_MAX : min;
+ re->minlength = (min > (int)UINT16_MAX)? (int)UINT16_MAX : min;
break;
}
}
diff --git a/src/3rdparty/pcre2/src/pcre2_substitute.c b/src/3rdparty/pcre2/src/pcre2_substitute.c
index 17040ce5fd4..5cb84748e0e 100644
--- a/src/3rdparty/pcre2/src/pcre2_substitute.c
+++ b/src/3rdparty/pcre2/src/pcre2_substitute.c
@@ -39,12 +39,10 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
+
+
#define PTR_STACK_SIZE 20
#define SUBSTITUTE_OPTIONS \
@@ -131,7 +129,6 @@ for (; ptr < ptrend; ptr++)
ptr += 1; /* Must point after \ */
erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode,
code->overall_options, code->extra_options, code->top_bracket, FALSE, NULL);
- ptr -= 1; /* Back to last code unit of escape */
if (errorcode != 0)
{
/* errorcode from check_escape is positive, so must not be returned by
@@ -327,9 +324,11 @@ if (input_len == 0) return 0;
switch (state->to_case)
{
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return 0;
+ /* LCOV_EXCL_STOP */
case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE
case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE
@@ -465,9 +464,11 @@ PCRE2_ASSERT(input_len != 0);
switch (state->to_case)
{
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return 0;
+ /* LCOV_EXCL_STOP */
case PCRE2_SUBSTITUTE_CASE_LOWER: // Can be single_char TRUE or FALSE
case PCRE2_SUBSTITUTE_CASE_UPPER: // Can only be single_char FALSE
@@ -751,12 +752,14 @@ BOOL use_existing_match;
BOOL replacement_only;
BOOL utf = (code->overall_options & PCRE2_UTF) != 0;
PCRE2_UCHAR temp[6];
+PCRE2_UCHAR null_str[1] = { 0xcd };
+PCRE2_SPTR original_subject = subject;
PCRE2_SPTR ptr;
PCRE2_SPTR repend = NULL;
PCRE2_SIZE extra_needed = 0;
PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength;
PCRE2_SIZE *ovector;
-PCRE2_SIZE ovecsave[3];
+PCRE2_SIZE ovecsave[2] = { 0, 0 };
pcre2_substitute_callout_block scb;
PCRE2_SIZE sub_start_extra_needed;
PCRE2_SIZE (*substitute_case_callout)(PCRE2_SPTR, PCRE2_SIZE, PCRE2_UCHAR *,
@@ -768,7 +771,6 @@ void *substitute_case_callout_data = NULL;
buff_offset = 0;
lengthleft = buff_length = *blength;
*blength = PCRE2_UNSET;
-ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET;
if (mcontext != NULL)
{
@@ -788,18 +790,74 @@ zero length is interpreted as an empty string. */
if (replacement == NULL)
{
if (rlength != 0) return PCRE2_ERROR_NULL;
- replacement = (PCRE2_SPTR)"";
+ replacement = null_str;
}
if (rlength == PCRE2_ZERO_TERMINATED) rlength = PRIV(strlen)(replacement);
repend = replacement + rlength;
+/* A NULL subject of zero length is treated as an empty string. */
+
+if (subject == NULL)
+ {
+ if (length != 0) return PCRE2_ERROR_NULL;
+ subject = null_str;
+ }
+
+if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject);
+
/* Check for using a match that has already happened. Note that the subject
pointer in the match data may be NULL after a no-match. */
use_existing_match = ((options & PCRE2_SUBSTITUTE_MATCHED) != 0);
replacement_only = ((options & PCRE2_SUBSTITUTE_REPLACEMENT_ONLY) != 0);
+if (use_existing_match && match_data == NULL) return PCRE2_ERROR_NULL;
+
+/* If an existing match is being passed in, we should check that it matches
+the passed-in subject pointer, length, and match options. We don't currently
+have a use-case for someone to match on one subject, then try and use that
+match data on a different subject. In a UTF-encoded string, a simple change
+like replacing one character for another won't preserve the code unit offsets,
+so it's hard to see, in the general case, how it would be safe or useful to
+support swapping or mutating the subject string.
+
+Similarly, using different match options between the first (external) and
+subsequent (internal, global) matches is hard to justify. */
+
+if (use_existing_match)
+ {
+ /* Return early, as the rest of the match_data may not have been
+ initialised. This duplicates and must be in sync with the check below that
+ aborts substitution on any result other than success or no-match. */
+ if (match_data->rc < 0 && match_data->rc != PCRE2_ERROR_NOMATCH)
+ return match_data->rc;
+
+ /* Not supported if the passed-in match was from the DFA interpreter. */
+ if (match_data->matchedby == PCRE2_MATCHEDBY_DFA_INTERPRETER)
+ return PCRE2_ERROR_DFA_UFUNC;
+
+ if (code != match_data->code)
+ return PCRE2_ERROR_DIFFSUBSPATTERN;
+
+ /* We want the passed-in subject strings to match. This implies the effective
+ length must match, and either: the pointers are equal (with strict matching
+ of NULL against NULL); or, the special case of PCRE2_COPY_MATCHED_SUBJECT
+ where we cannot compare pointers but we can verify the contents. */
+ if (length != match_data->subject_length ||
+ !(original_subject == match_data->subject ||
+ ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0 &&
+ (length == 0 ||
+ memcmp(subject, match_data->subject, CU2BYTES(length)) == 0))))
+ return PCRE2_ERROR_DIFFSUBSSUBJECT;
+
+ if (start_offset != match_data->start_offset)
+ return PCRE2_ERROR_DIFFSUBSOFFSET;
+
+ if ((options & ~SUBSTITUTE_OPTIONS) != match_data->options)
+ return PCRE2_ERROR_DIFFSUBSOPTIONS;
+ }
+
/* If starting from an existing match, there must be an externally provided
match data block. We create an internal match_data block in two cases: (a) an
external one is not supplied (and we are not starting from an existing match);
@@ -816,9 +874,8 @@ have to be changes below. */
if (match_data == NULL)
{
pcre2_general_context gcontext;
- if (use_existing_match) return PCRE2_ERROR_NULL;
gcontext.memctl = (mcontext == NULL)?
- ((const pcre2_real_code *)code)->memctl :
+ ((pcre2_real_code *)code)->memctl :
((pcre2_real_match_context *)mcontext)->memctl;
match_data = internal_match_data =
pcre2_match_data_create_from_pattern(code, &gcontext);
@@ -830,7 +887,7 @@ else if (use_existing_match)
int pairs;
pcre2_general_context gcontext;
gcontext.memctl = (mcontext == NULL)?
- ((const pcre2_real_code *)code)->memctl :
+ ((pcre2_real_code *)code)->memctl :
((pcre2_real_match_context *)mcontext)->memctl;
pairs = (code->top_bracket + 1 < match_data->oveccount)?
code->top_bracket + 1 : match_data->oveccount;
@@ -841,9 +898,15 @@ else if (use_existing_match)
+ 2*pairs*sizeof(PCRE2_SIZE));
internal_match_data->heapframes = NULL;
internal_match_data->heapframes_size = 0;
+ /* Ensure that the subject is not freed when internal_match_data is */
+ internal_match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT;
match_data = internal_match_data;
}
+/* If using an internal match data, there's no need to copy the subject. */
+
+if (internal_match_data != NULL) options &= ~PCRE2_COPY_MATCHED_SUBJECT;
+
/* Remember ovector details */
ovector = pcre2_get_ovector_pointer(match_data);
@@ -856,19 +919,6 @@ scb.input = subject;
scb.output = (PCRE2_SPTR)buffer;
scb.ovector = ovector;
-/* A NULL subject of zero length is treated as an empty string. */
-
-if (subject == NULL)
- {
- if (length != 0) return PCRE2_ERROR_NULL;
- subject = (PCRE2_SPTR)"";
- }
-
-/* Find length of zero-terminated subject */
-
-if (length == PCRE2_ZERO_TERMINATED)
- length = subject? PRIV(strlen)(subject) : 0;
-
/* Check UTF replacement string if necessary. */
#ifdef SUPPORT_UNICODE
@@ -905,7 +955,7 @@ if (!replacement_only) CHECKMEMCPY(subject, start_offset);
match is taken from the match_data that was passed in. */
subs = 0;
-do
+for (;;)
{
PCRE2_SPTR ptrstack[PTR_STACK_SIZE];
uint32_t ptrstackptr = 0;
@@ -925,54 +975,12 @@ do
if (utf) options |= PCRE2_NO_UTF_CHECK; /* Only need to check once */
#endif
- /* Any error other than no match returns the error code. No match when not
- doing the special after-empty-match global rematch, or when at the end of the
- subject, breaks the global loop. Otherwise, advance the starting point by one
- character, copying it to the output, and try again. */
-
- if (rc < 0)
- {
- PCRE2_SIZE save_start;
-
- if (rc != PCRE2_ERROR_NOMATCH) goto EXIT;
- if (goptions == 0 || start_offset >= length) break;
-
- /* Advance by one code point. Then, if CRLF is a valid newline sequence and
- we have advanced into the middle of it, advance one more code point. In
- other words, do not start in the middle of CRLF, even if CR and LF on their
- own are valid newlines. */
-
- save_start = start_offset++;
- if (subject[start_offset-1] == CHAR_CR &&
- (code->newline_convention == PCRE2_NEWLINE_CRLF ||
- code->newline_convention == PCRE2_NEWLINE_ANY ||
- code->newline_convention == PCRE2_NEWLINE_ANYCRLF) &&
- start_offset < length &&
- subject[start_offset] == CHAR_LF)
- start_offset++;
-
- /* Otherwise, in UTF mode, advance past any secondary code points. */
+ /* Any error other than no match returns the error code. No match breaks the
+ global loop. */
- else if ((code->overall_options & PCRE2_UTF) != 0)
- {
-#if PCRE2_CODE_UNIT_WIDTH == 8
- while (start_offset < length && (subject[start_offset] & 0xc0) == 0x80)
- start_offset++;
-#elif PCRE2_CODE_UNIT_WIDTH == 16
- while (start_offset < length &&
- (subject[start_offset] & 0xfc00) == 0xdc00)
- start_offset++;
-#endif
- }
+ if (rc == PCRE2_ERROR_NOMATCH) break;
- /* Copy what we have advanced past (unless not required), reset the special
- global options, and continue to the next match. */
-
- fraglength = start_offset - save_start;
- if (!replacement_only) CHECKMEMCPY(subject + save_start, fraglength);
- goptions = 0;
- continue;
- }
+ if (rc < 0) goto EXIT;
/* Handle a successful match. Matches that use \K to end before they start
or start before the current point in the subject are not supported. */
@@ -983,25 +991,27 @@ do
goto EXIT;
}
- /* Check for the same match as previous. This is legitimate after matching an
- empty string that starts after the initial match offset. We have tried again
- at the match point in case the pattern is one like /(?<=\G.)/ which can never
- match at its starting point, so running the match achieves the bumpalong. If
- we do get the same (null) match at the original match point, it isn't such a
- pattern, so we now do the empty string magic. In all other cases, a repeat
- match should never occur. */
+ /* Assert that our replacement loop is making progress, checked even in
+ release builds. This should be impossible to hit, however, an infinite loop
+ would be fairly catastrophic.
- if (ovecsave[0] == ovector[0] && ovecsave[1] == ovector[1])
+ "Progress" is measured as ovector[1] strictly advancing, or, an empty match
+ after a non-empty match. */
+
+ /* LCOV_EXCL_START */
+ if (subs > 0 &&
+ !(ovector[1] > ovecsave[1] ||
+ (ovector[1] == ovector[0] && ovecsave[1] > ovecsave[0] &&
+ ovector[1] == ovecsave[1])))
{
- if (ovector[0] == ovector[1] && ovecsave[2] != start_offset)
- {
- goptions = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;
- ovecsave[2] = start_offset;
- continue; /* Back to the top of the loop */
- }
+ PCRE2_DEBUG_UNREACHABLE();
rc = PCRE2_ERROR_INTERNAL_DUPMATCH;
goto EXIT;
}
+ /* LCOV_EXCL_STOP */
+
+ ovecsave[0] = ovector[0];
+ ovecsave[1] = ovector[1];
/* Count substitutions with a paranoid check for integer overflow; surely no
real call to this function would ever hit this! */
@@ -1133,6 +1143,44 @@ do
subptrend = subject + length;
goto SUBPTR_SUBSTITUTE;
}
+ else if (next == CHAR_PLUS &&
+ !(ptr+1 < repend && ptr[1] == CHAR_LEFT_CURLY_BRACKET))
+ {
+ /* Perl supports $+ for "highest captured group" (not the same as $^N
+ which is mainly only useful inside Perl's match callbacks). We also
+ don't accept "$+{..." since that's Perl syntax for our ${name}. */
+ ++ptr;
+ if (code->top_bracket == 0)
+ {
+ /* Treat either as "no such group" or "all groups unset" based on the
+ PCRE2_SUBSTITUTE_UNKNOWN_UNSET option. */
+ if ((suboptions & PCRE2_SUBSTITUTE_UNKNOWN_UNSET) == 0)
+ {
+ rc = PCRE2_ERROR_NOSUBSTRING;
+ goto PTREXIT;
+ }
+ group = 0;
+ }
+ else
+ {
+ /* If we have any capture groups, then the ovector needs to be large
+ enough for all of them, or the result won't be accurate. */
+ if (match_data->oveccount < code->top_bracket + 1)
+ {
+ rc = PCRE2_ERROR_UNAVAILABLE;
+ goto PTREXIT;
+ }
+ for (group = code->top_bracket; group > 0; group--)
+ if (ovector[2*group] != PCRE2_UNSET) break;
+ }
+ if (group == 0)
+ {
+ if ((suboptions & PCRE2_SUBSTITUTE_UNSET_EMPTY) != 0) continue;
+ rc = PCRE2_ERROR_UNSET;
+ goto PTREXIT;
+ }
+ goto GROUP_SUBSTITUTE;
+ }
if (next == CHAR_LEFT_CURLY_BRACKET)
{
@@ -1627,19 +1675,25 @@ do
}
}
- /* Save the details of this match. See above for how this data is used. If we
- matched an empty string, do the magic for global matches. Update the start
- offset to point to the rest of the subject string. If we re-used an existing
- match for the first match, switch to the internal match data block. */
+ /* Exit the global loop if we are not in global mode, or if pcre2_next_match()
+ indicates we have reached the end of the subject. */
- ovecsave[0] = ovector[0];
- ovecsave[1] = ovector[1];
- ovecsave[2] = start_offset;
+ if ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) == 0 ||
+ !pcre2_next_match(match_data, &start_offset, &goptions))
+ {
+ start_offset = ovector[1];
+ break;
+ }
+
+ /* Verify that pcre2_next_match() has not done a bumpalong (because we have
+ already returned PCRE2_ERROR_BADSUBSPATTERN for \K in lookarounds).
+
+ We would otherwise have to memcpy the fragment spanning from ovector[1] to the
+ new start_offset.*/
+
+ PCRE2_ASSERT(start_offset == ovector[1]);
- goptions = (ovector[0] != ovector[1] || ovector[0] > start_offset)? 0 :
- PCRE2_ANCHORED|PCRE2_NOTEMPTY_ATSTART;
- start_offset = ovector[1];
- } while ((suboptions & PCRE2_SUBSTITUTE_GLOBAL) != 0); /* Repeat "do" loop */
+ } /* End of global loop */
/* Copy the rest of the subject unless not required, and terminate the output
with a binary zero. */
diff --git a/src/3rdparty/pcre2/src/pcre2_substring.c b/src/3rdparty/pcre2/src/pcre2_substring.c
index 88afd2348bb..f68b464e058 100644
--- a/src/3rdparty/pcre2/src/pcre2_substring.c
+++ b/src/3rdparty/pcre2/src/pcre2_substring.c
@@ -39,10 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
*/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
#include "pcre2_internal.h"
@@ -126,7 +122,7 @@ PCRE2_SIZE size;
rc = pcre2_substring_length_bynumber(match_data, stringnumber, &size);
if (rc < 0) return rc;
if (size + 1 > *sizeptr) return PCRE2_ERROR_NOMEMORY;
-memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],
+if (size != 0) memcpy(buffer, match_data->subject + match_data->ovector[stringnumber*2],
CU2BYTES(size));
buffer[size] = 0;
*sizeptr = size;
@@ -218,7 +214,7 @@ yield = PRIV(memctl_malloc)(sizeof(pcre2_memctl) +
(size + 1)*PCRE2_CODE_UNIT_WIDTH, (pcre2_memctl *)match_data);
if (yield == NULL) return PCRE2_ERROR_NOMEMORY;
yield = (PCRE2_UCHAR *)(((char *)yield) + sizeof(pcre2_memctl));
-memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
+if (size != 0) memcpy(yield, match_data->subject + match_data->ovector[stringnumber*2],
CU2BYTES(size));
yield[size] = 0;
*stringptr = yield;
@@ -259,7 +255,7 @@ permits duplicate names, the first substring that is set is chosen.
Arguments:
match_data pointer to match data
stringname the name of the required substring
- sizeptr where to put the length
+ sizeptr where to put the length, if not NULL
Returns: 0 if successful, else a negative error number
*/
@@ -342,8 +338,15 @@ else /* Matched using pcre2_dfa_match() */
left = match_data->ovector[stringnumber*2];
right = match_data->ovector[stringnumber*2+1];
+/* LCOV_EXCL_START - this appears to be unreachable, as the ovector and
+subject_length should always be set consistently, no matter what misbehaviour
+the caller has committed. */
if (left > match_data->subject_length || right > match_data->subject_length)
+ {
+ PCRE2_DEBUG_UNREACHABLE();
return PCRE2_ERROR_INVALIDOFFSET;
+ }
+/* LCOV_EXCL_STOP */
if (sizeptr != NULL) *sizeptr = (left > right)? 0 : right - left;
return 0;
}
diff --git a/src/3rdparty/pcre2/src/pcre2_tables.c b/src/3rdparty/pcre2/src/pcre2_tables.c
index 097a1acca87..0b9b43bf2e5 100644
--- a/src/3rdparty/pcre2/src/pcre2_tables.c
+++ b/src/3rdparty/pcre2/src/pcre2_tables.c
@@ -38,27 +38,33 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains some fixed tables that are used by more than one of the
PCRE2 code modules. The tables are also #included by the pcre2test program,
which uses macros to change their names from _pcre2_xxx to xxxx, thereby
avoiding name clashes with the library. In this case, PCRE2_PCRE2TEST is
defined. */
-#ifndef PCRE2_PCRE2TEST /* We're compiling the library */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+
+#if !defined(PCRE2_PCRE2TEST) && !defined(PCRE2_DFTABLES) && \
+ !defined(PCRE2_PCRE2POSIX) /* We're compiling the library */
#include "pcre2_internal.h"
-#endif /* PCRE2_PCRE2TEST */
+#endif
+
+
+/* Utility macros */
+#define ARR_SIZE(x) sizeof(x)/sizeof(x[0])
+
+
+#if !defined(PCRE2_PCRE2TEST) && !defined(PCRE2_DFTABLES) && \
+ !defined(PCRE2_PCRE2POSIX)
/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
the definition is next to the definition of the opcodes in pcre2_internal.h.
This is mode-dependent, so it is skipped when this file is included by
pcre2test. */
-#ifndef PCRE2_PCRE2TEST
const uint8_t PRIV(OP_lengths)[] = { OP_LENGTHS };
-#endif
/* Tables of horizontal and vertical whitespace characters, suitable for
adding to classes. */
@@ -66,6 +72,11 @@ adding to classes. */
const uint32_t PRIV(hspace_list)[] = { HSPACE_LIST };
const uint32_t PRIV(vspace_list)[] = { VSPACE_LIST };
+#endif /* !PCRE2_PCRE2TEST && !PCRE2_DFTABLES && !PCRE2_PCRE2POSIX */
+
+
+#if !defined(PCRE2_DFTABLES) && !defined(PCRE2_PCRE2POSIX)
+
/* These tables are the pairs of delimiters that are valid for callout string
arguments. For each starting delimiter there must be a matching ending
delimiter, which in fact is different only for bracket-like delimiters. */
@@ -80,6 +91,8 @@ const uint32_t PRIV(callout_end_delims[]) = {
CHAR_CIRCUMFLEX_ACCENT, CHAR_PERCENT_SIGN, CHAR_NUMBER_SIGN,
CHAR_DOLLAR_SIGN, CHAR_RIGHT_CURLY_BRACKET, 0 };
+#endif /* !PCRE2_DFTABLES && !PCRE2_PCRE2POSIX */
+
/*************************************************
* Tables for UTF-8 support *
@@ -90,23 +103,24 @@ as for the library in 8-bit mode, because pcre2test uses UTF-8 internally for
handling wide characters. */
#if defined PCRE2_PCRE2TEST || \
- (defined SUPPORT_UNICODE && \
- defined PCRE2_CODE_UNIT_WIDTH && \
- PCRE2_CODE_UNIT_WIDTH == 8)
+ (!defined(PCRE2_DFTABLES) && !defined(PCRE2_PCRE2POSIX) && \
+ defined SUPPORT_UNICODE && \
+ defined PCRE2_CODE_UNIT_WIDTH && \
+ PCRE2_CODE_UNIT_WIDTH == 8)
/* These are the breakpoints for different numbers of bytes in a UTF-8
character. */
const int PRIV(utf8_table1)[] =
- { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
+ { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff };
-const int PRIV(utf8_table1_size) = sizeof(PRIV(utf8_table1)) / sizeof(int);
+const unsigned PRIV(utf8_table1_size) = ARR_SIZE(PRIV(utf8_table1));
/* These are the indicator bits and the mask for the data bits to set in the
first byte of a character, indexed by the number of additional bytes. */
-const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
-const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+const int PRIV(utf8_table2)[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc };
+const int PRIV(utf8_table3)[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
/* Table of the number of extra bytes, indexed by the first byte masked with
0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
@@ -120,10 +134,11 @@ const uint8_t PRIV(utf8_table4)[] = {
#endif /* UTF-8 support needed */
/* Tables concerned with Unicode properties are relevant only when Unicode
-support is enabled. See also the pcre2_ucptables.c file, which is generated by
+support is enabled. See also the pcre2_ucptables_inc.h file, which is generated by
a Python script from Unicode data files. */
-#ifdef SUPPORT_UNICODE
+#if !defined(PCRE2_DFTABLES) && !defined(PCRE2_PCRE2POSIX) && \
+ defined(SUPPORT_UNICODE)
/* Table to translate from particular type value to the general value. */
@@ -227,8 +242,69 @@ const int PRIV(ucp_typerange)[] = {
/* Finally, include the tables that are auto-generated from the Unicode data
files. */
-#include "pcre2_ucptables.c"
+#include "pcre2_ucptables_inc.h"
+
+#endif /* Unicode support needed */
+
+
+/*************************************************
+* Tables for EBCDIC support *
+*************************************************/
+
+#if defined(EBCDIC) && \
+ (defined(PCRE2_PCRE2TEST) || defined(PCRE2_DFTABLES) || 'a' != 0x81)
+
+const uint8_t PRIV(ebcdic_1047_to_ascii)[256] = {
+ 0x00,0x01,0x02,0x03,0x9c,0x09,0x86,0x7f,0x97,0x8d,0x8e,0x0b,0x0c,0x0d,0x0e,0x0f,
+#ifdef EBCDIC_NL25
+ 0x10,0x11,0x12,0x13,0x9d,0x85,0x08,0x87,0x18,0x19,0x92,0x8f,0x1c,0x1d,0x1e,0x1f,
+ 0x80,0x81,0x82,0x83,0x84,0x0a,0x17,0x1b,0x88,0x89,0x8a,0x8b,0x8c,0x05,0x06,0x07,
+#else
+ 0x10,0x11,0x12,0x13,0x9d,0x0a,0x08,0x87,0x18,0x19,0x92,0x8f,0x1c,0x1d,0x1e,0x1f,
+ 0x80,0x81,0x82,0x83,0x84,0x85,0x17,0x1b,0x88,0x89,0x8a,0x8b,0x8c,0x05,0x06,0x07,
+#endif
+ 0x90,0x91,0x16,0x93,0x94,0x95,0x96,0x04,0x98,0x99,0x9a,0x9b,0x14,0x15,0x9e,0x1a,
+ 0x20,0xa0,0xe2,0xe4,0xe0,0xe1,0xe3,0xe5,0xe7,0xf1,0xa2,0x2e,0x3c,0x28,0x2b,0x7c,
+ 0x26,0xe9,0xea,0xeb,0xe8,0xed,0xee,0xef,0xec,0xdf,0x21,0x24,0x2a,0x29,0x3b,0x5e,
+ 0x2d,0x2f,0xc2,0xc4,0xc0,0xc1,0xc3,0xc5,0xc7,0xd1,0xa6,0x2c,0x25,0x5f,0x3e,0x3f,
+ 0xf8,0xc9,0xca,0xcb,0xc8,0xcd,0xce,0xcf,0xcc,0x60,0x3a,0x23,0x40,0x27,0x3d,0x22,
+ 0xd8,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0xab,0xbb,0xf0,0xfd,0xfe,0xb1,
+ 0xb0,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0xaa,0xba,0xe6,0xb8,0xc6,0xa4,
+ 0xb5,0x7e,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0xa1,0xbf,0xd0,0x5b,0xde,0xae,
+ 0xac,0xa3,0xa5,0xb7,0xa9,0xa7,0xb6,0xbc,0xbd,0xbe,0xdd,0xa8,0xaf,0x5d,0xb4,0xd7,
+ 0x7b,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0xad,0xf4,0xf6,0xf2,0xf3,0xf5,
+ 0x7d,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xb9,0xfb,0xfc,0xf9,0xfa,0xff,
+ 0x5c,0xf7,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0xb2,0xd4,0xd6,0xd2,0xd3,0xd5,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0xb3,0xdb,0xdc,0xd9,0xda,0x9f,
+};
+
+const uint8_t PRIV(ascii_to_ebcdic_1047)[256] = {
+#ifdef EBCDIC_NL25
+ 0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f,0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,
+#else
+ 0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f,0x16,0x05,0x15,0x0b,0x0c,0x0d,0x0e,0x0f,
+#endif
+ 0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26,0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,
+ 0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d,0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,
+ 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,
+ 0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,
+ 0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xad,0xe0,0xbd,0x5f,0x6d,
+ 0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,
+ 0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,
+#ifdef EBCDIC_NL25
+ 0x20,0x21,0x22,0x23,0x24,0x15,0x06,0x17,0x28,0x29,0x2a,0x2b,0x2c,0x09,0x0a,0x1b,
+#else
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x06,0x17,0x28,0x29,0x2a,0x2b,0x2c,0x09,0x0a,0x1b,
+#endif
+ 0x30,0x31,0x1a,0x33,0x34,0x35,0x36,0x08,0x38,0x39,0x3a,0x3b,0x04,0x14,0x3e,0xff,
+ 0x41,0xaa,0x4a,0xb1,0x9f,0xb2,0x6a,0xb5,0xbb,0xb4,0x9a,0x8a,0xb0,0xca,0xaf,0xbc,
+ 0x90,0x8f,0xea,0xfa,0xbe,0xa0,0xb6,0xb3,0x9d,0xda,0x9b,0x8b,0xb7,0xb8,0xb9,0xab,
+ 0x64,0x65,0x62,0x66,0x63,0x67,0x9e,0x68,0x74,0x71,0x72,0x73,0x78,0x75,0x76,0x77,
+ 0xac,0x69,0xed,0xee,0xeb,0xef,0xec,0xbf,0x80,0xfd,0xfe,0xfb,0xfc,0xba,0xae,0x59,
+ 0x44,0x45,0x42,0x46,0x43,0x47,0x9c,0x48,0x54,0x51,0x52,0x53,0x58,0x55,0x56,0x57,
+ 0x8c,0x49,0xcd,0xce,0xcb,0xcf,0xcc,0xe1,0x70,0xdd,0xde,0xdb,0xdc,0x8d,0x8e,0xdf,
+};
-#endif /* SUPPORT_UNICODE */
+#endif /* EBCDIC support needed */
/* End of pcre2_tables.c */
diff --git a/src/3rdparty/pcre2/src/pcre2_ucd.c b/src/3rdparty/pcre2/src/pcre2_ucd.c
index 4c5e5163b3a..1cbff3afecb 100644
--- a/src/3rdparty/pcre2/src/pcre2_ucd.c
+++ b/src/3rdparty/pcre2/src/pcre2_ucd.c
@@ -42,6 +42,7 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This file contains tables of Unicode properties that are extracted from
Unicode data files. See the comments at the start of maint/GenerateUcd.py for
details.
@@ -52,13 +53,13 @@ _pcre2_xxx to xxxx, thereby avoiding name clashes with the library. At present,
just one of these tables is actually needed. When compiling the library, some
headers are needed. */
+
#ifndef PCRE2_PCRE2TEST
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include "pcre2_internal.h"
#endif /* PCRE2_PCRE2TEST */
+
+
/* The tables herein are needed only when UCP support is built, and in PCRE2
that happens automatically with UTF support. This module should not be
referenced otherwise, so it should not matter whether it is compiled or not.
diff --git a/src/3rdparty/pcre2/src/pcre2_ucptables.c b/src/3rdparty/pcre2/src/pcre2_ucptables_inc.h
index d2b34037bea..6f1731d32c8 100644
--- a/src/3rdparty/pcre2/src/pcre2_ucptables.c
+++ b/src/3rdparty/pcre2/src/pcre2_ucptables_inc.h
@@ -1593,4 +1593,4 @@ const size_t PRIV(utt_size) = sizeof(PRIV(utt)) / sizeof(ucp_type_table);
#endif /* SUPPORT_UNICODE */
-/* End of pcre2_ucptables.c */
+/* End of pcre2_ucptables_inc.h */
diff --git a/src/3rdparty/pcre2/src/pcre2_util.h b/src/3rdparty/pcre2/src/pcre2_util.h
index ea8635552a1..7bfbee09952 100644
--- a/src/3rdparty/pcre2/src/pcre2_util.h
+++ b/src/3rdparty/pcre2/src/pcre2_util.h
@@ -71,6 +71,8 @@ side-effects. */
} while(0)
#endif
+/* LCOV_EXCL_START */
+
/* PCRE2_UNREACHABLE() can be used to mark locations on the code that
shouldn't be reached. In non debug builds is defined as a hint for
the compiler to eliminate any code after it, so it is useful also for
@@ -107,8 +109,16 @@ the reason and the actions that should be taken if it ever triggers. */
#define PCRE2_DEBUG_UNREACHABLE() PCRE2_UNREACHABLE()
+/* LCOV_EXCL_STOP */
+
#endif /* PCRE2_DEBUG */
+#ifndef PCRE2_ASSERT
+#define PCRE2_ASSERT(x) do {} while(0)
+#endif
+
+/* LCOV_EXCL_START */
+
#ifndef PCRE2_DEBUG_UNREACHABLE
#define PCRE2_DEBUG_UNREACHABLE() do {} while(0)
#endif
@@ -123,8 +133,45 @@ the reason and the actions that should be taken if it ever triggers. */
#endif
#endif /* !PCRE2_UNREACHABLE */
-#ifndef PCRE2_ASSERT
-#define PCRE2_ASSERT(x) do {} while(0)
+/* LCOV_EXCL_STOP */
+
+/* We define this fallthrough macro for suppressing -Wimplicit-fallthrough warnings.
+Clang only allows this via an attribute, whereas other compilers (eg. GCC) match attributes
+and also specially-formatted comments.
+
+This macro should be used with no following semicolon, and ideally with a comment: */
+
+// PCRE2_FALLTHROUGH /* Fall through */
+
+#ifndef PCRE2_FALLTHROUGH
+
+#if defined(__cplusplus) && __cplusplus >= 202002L && \
+ defined(__has_cpp_attribute)
+/* Standards-compatible C++ variant. */
+#if __has_cpp_attribute(fallthrough)
+#define PCRE2_FALLTHROUGH [[fallthrough]];
+#endif
+#elif !defined(__cplusplus) && \
+ defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L && \
+ defined(__has_c_attribute)
+/* Standards-compatible C variant. */
+#if __has_c_attribute(fallthrough)
+#define PCRE2_FALLTHROUGH [[fallthrough]];
+#endif
+#elif ((defined(__clang__) && __clang_major__ >= 10) || \
+ (defined(__GNUC__) && __GNUC__ >= 7)) && \
+ defined(__has_attribute)
+/* Clang and GCC syntax. Rule out old versions because apparently Clang at
+ least has a broken implementation of __has_attribute. */
+#if __has_attribute(fallthrough)
+#define PCRE2_FALLTHROUGH __attribute__((fallthrough));
+#endif
+#endif
+
+#endif /* !PCRE2_FALLTHROUGH */
+
+#ifndef PCRE2_FALLTHROUGH
+#define PCRE2_FALLTHROUGH
#endif
#endif /* PCRE2_UTIL_H_IDEMPOTENT_GUARD */
diff --git a/src/3rdparty/pcre2/src/pcre2_valid_utf.c b/src/3rdparty/pcre2/src/pcre2_valid_utf.c
index de411b919e1..3fac931ea94 100644
--- a/src/3rdparty/pcre2/src/pcre2_valid_utf.c
+++ b/src/3rdparty/pcre2/src/pcre2_valid_utf.c
@@ -44,14 +44,13 @@ strings. This file is also #included by the pcre2test program, which uses
macros to change names from _pcre2_xxx to xxxx, thereby avoiding name clashes
with the library. In this case, PCRE2_PCRE2TEST is defined. */
+
#ifndef PCRE2_PCRE2TEST /* We're compiling the library */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
#include "pcre2_internal.h"
#endif /* PCRE2_PCRE2TEST */
+
#ifndef SUPPORT_UNICODE
/*************************************************
* Dummy function when Unicode is not supported *
diff --git a/src/3rdparty/pcre2/src/pcre2_xclass.c b/src/3rdparty/pcre2/src/pcre2_xclass.c
index 25de7cbf38b..7bcae34e0a3 100644
--- a/src/3rdparty/pcre2/src/pcre2_xclass.c
+++ b/src/3rdparty/pcre2/src/pcre2_xclass.c
@@ -38,17 +38,15 @@ POSSIBILITY OF SUCH DAMAGE.
-----------------------------------------------------------------------------
*/
+
/* This module contains two internal functions that are used to match
OP_XCLASS and OP_ECLASS. It is used by pcre2_auto_possessify() and by both
pcre2_match() and pcre2_dfa_match(). */
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
+#include "pcre2_internal.h"
-#include "pcre2_internal.h"
/*************************************************
* Match character against an XCLASS *
@@ -252,9 +250,11 @@ if (*data == XCL_PROP || *data == XCL_NOTPROP)
/* This should never occur, but compilers may mutter if there is no
default. */
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return FALSE;
+ /* LCOV_EXCL_STOP */
}
data += 2;
@@ -529,9 +529,11 @@ while (ptr < data_end)
/* This should never occur, but compilers may mutter if there is no
default. */
+ /* LCOV_EXCL_START */
default:
PCRE2_DEBUG_UNREACHABLE();
return FALSE;
+ /* LCOV_EXCL_STOP */
}
}
diff --git a/src/3rdparty/sha3/qt_attribution.json b/src/3rdparty/sha3/qt_attribution.json
index ddb440cbdbd..6c6a44e1b6b 100644
--- a/src/3rdparty/sha3/qt_attribution.json
+++ b/src/3rdparty/sha3/qt_attribution.json
@@ -8,7 +8,7 @@
"Files": "brg_endian.h",
"Description": "SHA-3, originally known as Keccak, is a cryptographic hash function.",
- "Version": "4b9e13ead2c5b5e41ca27c65de4dd69ae0bac228",
+ "Version": "1.0.0",
"PURL": "pkg:github/BrianGladman/sha@$<VERSION>",
"License": "BSD 2-clause \"Simplified\" License",
"LicenseFile": "BRG_ENDIAN_LICENSE",
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index babf5bc31d2..2920c743243 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -71,7 +71,6 @@ add_subdirectory(tools)
if(QT_FEATURE_gui)
add_subdirectory(gui)
- add_subdirectory(assets)
if(QT_FEATURE_opengl)
add_subdirectory(opengl)
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java
index 779b68954d8..1d4ec370d39 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtAccessibilityDelegate.java
@@ -514,17 +514,6 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate
boolean handled = false;
//Log.i(TAG, "PERFORM ACTION: " + action + " on " + virtualViewId);
switch (action) {
- case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
- // Only handle the FOCUS action if it's placing focus on
- // a different view that was previously focused.
- if (m_focusedVirtualViewId != virtualViewId) {
- m_focusedVirtualViewId = virtualViewId;
- m_view.invalidate();
- sendEventForVirtualViewId(virtualViewId,
- AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED);
- handled = true;
- }
- break;
case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS:
if (m_focusedVirtualViewId == virtualViewId) {
m_focusedVirtualViewId = INVALID_ID;
@@ -565,17 +554,19 @@ class QtAccessibilityDelegate extends View.AccessibilityDelegate
sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_CLICKED);
break;
case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
- success = QtNativeAccessibility.focusAction(virtualViewId);
+ if (m_focusedVirtualViewId != virtualViewId) {
+ success = QtNativeAccessibility.focusAction(virtualViewId);
+ if (!success) {
+ notifyObjectFocus(virtualViewId);
+ success = true;
+ }
+ }
break;
case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD:
success = QtNativeAccessibility.scrollForward(virtualViewId);
- if (success)
- sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_SCROLLED);
break;
case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD:
success = QtNativeAccessibility.scrollBackward(virtualViewId);
- if (success)
- sendEventForVirtualViewId(virtualViewId, AccessibilityEvent.TYPE_VIEW_SCROLLED);
break;
}
return success;
diff --git a/src/assets/CMakeLists.txt b/src/assets/CMakeLists.txt
deleted file mode 100644
index ab07d27696e..00000000000
--- a/src/assets/CMakeLists.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright (C) 2024 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-if (NOT INTEGRITY AND TARGET Qt6::Network AND TARGET Qt6::Concurrent)
- add_subdirectory(downloader)
-endif()
diff --git a/src/assets/downloader/CMakeLists.txt b/src/assets/downloader/CMakeLists.txt
deleted file mode 100644
index 6b0564e72af..00000000000
--- a/src/assets/downloader/CMakeLists.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright (C) 2024 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-qt_internal_add_module(ExamplesAssetDownloaderPrivate
- CONFIG_MODULE_NAME examples_asset_downloader
- STATIC
- INTERNAL_MODULE
- SOURCES
- assetdownloader.cpp assetdownloader.h
- tasking/barrier.cpp tasking/barrier.h
- tasking/concurrentcall.h
- tasking/conditional.cpp tasking/conditional.h
- tasking/networkquery.cpp tasking/networkquery.h
- tasking/qprocesstask.cpp tasking/qprocesstask.h
- tasking/tasking_global.h
- tasking/tasktree.cpp tasking/tasktree.h
- tasking/tasktreerunner.cpp tasking/tasktreerunner.h
- tasking/tcpsocket.cpp tasking/tcpsocket.h
- DEFINES
- QT_NO_CAST_FROM_ASCII
- LIBRARIES
- Qt6::CorePrivate
- PUBLIC_LIBRARIES
- Qt6::Concurrent
- Qt6::Core
- Qt6::Network
- NO_GENERATE_CPP_EXPORTS
-)
-
-if (NOT QT_FEATURE_process)
- set_source_files_properties(tasking/qprocesstask.h PROPERTIES SKIP_AUTOMOC TRUE)
-endif()
diff --git a/src/assets/downloader/assetdownloader.cpp b/src/assets/downloader/assetdownloader.cpp
deleted file mode 100644
index 7c2f525a66d..00000000000
--- a/src/assets/downloader/assetdownloader.cpp
+++ /dev/null
@@ -1,592 +0,0 @@
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "assetdownloader.h"
-
-#include "tasking/concurrentcall.h"
-#include "tasking/networkquery.h"
-#include "tasking/tasktreerunner.h"
-
-#include <QtCore/private/qzipreader_p.h>
-
-#include <QtCore/QDir>
-#include <QtCore/QFile>
-#include <QtCore/QJsonArray>
-#include <QtCore/QJsonDocument>
-#include <QtCore/QJsonObject>
-#include <QtCore/QStandardPaths>
-#include <QtCore/QTemporaryDir>
-#include <QtCore/QTemporaryFile>
-
-using namespace Tasking;
-
-QT_BEGIN_NAMESPACE
-
-namespace Assets::Downloader {
-
-struct DownloadableAssets
-{
- QUrl remoteUrl;
- QList<QUrl> files;
-};
-
-class AssetDownloaderPrivate
-{
-public:
- AssetDownloaderPrivate(AssetDownloader *q) : m_q(q) {}
- AssetDownloader *m_q = nullptr;
-
- std::unique_ptr<QNetworkAccessManager> m_manager;
- std::unique_ptr<QTemporaryDir> m_temporaryDir;
- TaskTreeRunner m_taskTreeRunner;
- QString m_lastProgressText;
- QDir m_localDownloadDir;
-
- QString m_jsonFileName;
- QString m_zipFileName;
- QDir m_preferredLocalDownloadDir =
- QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
- QUrl m_offlineAssetsFilePath;
- QUrl m_downloadBase;
- QStringList m_networkErrors;
- QStringList m_sslErrors;
-
- void setLocalDownloadDir(const QDir &dir)
- {
- if (m_localDownloadDir != dir) {
- m_localDownloadDir = dir;
- emit m_q->localDownloadDirChanged(QUrl::fromLocalFile(m_localDownloadDir.absolutePath()));
- }
- }
- void setProgress(int progressValue, int progressMaximum, const QString &progressText)
- {
- m_lastProgressText = progressText;
- emit m_q->progressChanged(progressValue, progressMaximum, progressText);
- }
- void updateProgress(int progressValue, int progressMaximum)
- {
- setProgress(progressValue, progressMaximum, m_lastProgressText);
- }
- void clearProgress(const QString &progressText)
- {
- setProgress(0, 0, progressText);
- }
-
- void setupDownload(NetworkQuery *query, const QString &progressText)
- {
- query->setNetworkAccessManager(m_manager.get());
- clearProgress(progressText);
- QObject::connect(query, &NetworkQuery::started, query, [this, query] {
- QNetworkReply *reply = query->reply();
- QObject::connect(reply, &QNetworkReply::downloadProgress,
- query, [this](qint64 bytesReceived, qint64 totalBytes) {
- updateProgress((totalBytes > 0) ? 100.0 * bytesReceived / totalBytes : 0, 100);
- });
- QObject::connect(reply, &QNetworkReply::errorOccurred, query, [this, reply] {
- m_networkErrors << reply->errorString();
- });
-#if QT_CONFIG(ssl)
- QObject::connect(reply, &QNetworkReply::sslErrors,
- query, [this](const QList<QSslError> &sslErrors) {
- for (const QSslError &sslError : sslErrors)
- m_sslErrors << sslError.errorString();
- });
-#endif
- });
- }
-};
-
-static bool isWritableDir(const QDir &dir)
-{
- if (dir.exists()) {
- QTemporaryFile file(dir.filePath(QString::fromLatin1("tmp")));
- return file.open();
- }
- return false;
-}
-
-static bool sameFileContent(const QFileInfo &first, const QFileInfo &second)
-{
- if (first.exists() ^ second.exists())
- return false;
-
- if (first.size() != second.size())
- return false;
-
- QFile firstFile(first.absoluteFilePath());
- QFile secondFile(second.absoluteFilePath());
-
- if (firstFile.open(QFile::ReadOnly) && secondFile.open(QFile::ReadOnly)) {
- char char1;
- char char2;
- int readBytes1 = 0;
- int readBytes2 = 0;
- while (!firstFile.atEnd()) {
- readBytes1 = firstFile.read(&char1, 1);
- readBytes2 = secondFile.read(&char2, 1);
- if (readBytes1 != readBytes2 || readBytes1 != 1)
- return false;
- if (char1 != char2)
- return false;
- }
- return true;
- }
-
- return false;
-}
-
-static bool createDirectory(const QDir &dir)
-{
- if (dir.exists())
- return true;
-
- if (!createDirectory(dir.absoluteFilePath(QString::fromUtf8(".."))))
- return false;
-
- return dir.mkpath(QString::fromUtf8("."));
-}
-
-static bool canBeALocalBaseDir(const QDir &dir)
-{
- if (dir.exists())
- return !dir.isEmpty() || isWritableDir(dir);
- return createDirectory(dir) && isWritableDir(dir);
-}
-
-static QDir baseLocalDir(const QDir &preferredLocalDir)
-{
- if (canBeALocalBaseDir(preferredLocalDir))
- return preferredLocalDir;
-
- qWarning().noquote() << "AssetDownloader: Cannot set \"" << preferredLocalDir
- << "\" as a local download directory!";
- return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
-}
-
-static QString pathFromUrl(const QUrl &url)
-{
- if (url.isLocalFile())
- return url.toLocalFile();
-
- if (url.scheme() == u"qrc")
- return u":" + url.path();
-
- return url.toString();
-}
-
-static QList<QUrl> filterDownloadableAssets(const QList<QUrl> &assetFiles, const QDir &expectedDir)
-{
- QList<QUrl> downloadList;
- std::copy_if(assetFiles.begin(), assetFiles.end(), std::back_inserter(downloadList),
- [&](const QUrl &assetPath) {
- return !QFileInfo::exists(expectedDir.absoluteFilePath(assetPath.toString()));
- });
- return downloadList;
-}
-
-static bool allAssetsPresent(const QList<QUrl> &assetFiles, const QDir &expectedDir)
-{
- return std::all_of(assetFiles.begin(), assetFiles.end(), [&](const QUrl &assetPath) {
- return QFileInfo::exists(expectedDir.absoluteFilePath(assetPath.toString()));
- });
-}
-
-AssetDownloader::AssetDownloader(QObject *parent)
- : QObject(parent)
- , d(new AssetDownloaderPrivate(this))
-{}
-
-AssetDownloader::~AssetDownloader() = default;
-
-QUrl AssetDownloader::downloadBase() const
-{
- return d->m_downloadBase;
-}
-
-void AssetDownloader::setDownloadBase(const QUrl &downloadBase)
-{
- if (d->m_downloadBase != downloadBase) {
- d->m_downloadBase = downloadBase;
- emit downloadBaseChanged(d->m_downloadBase);
- }
-}
-
-QUrl AssetDownloader::preferredLocalDownloadDir() const
-{
- return QUrl::fromLocalFile(d->m_preferredLocalDownloadDir.absolutePath());
-}
-
-void AssetDownloader::setPreferredLocalDownloadDir(const QUrl &localDir)
-{
- if (localDir.scheme() == u"qrc") {
- qWarning() << "Cannot set a qrc as preferredLocalDownloadDir";
- return;
- }
-
- const QString path = pathFromUrl(localDir);
- if (d->m_preferredLocalDownloadDir != path) {
- d->m_preferredLocalDownloadDir.setPath(path);
- emit preferredLocalDownloadDirChanged(preferredLocalDownloadDir());
- }
-}
-
-QUrl AssetDownloader::offlineAssetsFilePath() const
-{
- return d->m_offlineAssetsFilePath;
-}
-
-void AssetDownloader::setOfflineAssetsFilePath(const QUrl &offlineAssetsFilePath)
-{
- if (d->m_offlineAssetsFilePath != offlineAssetsFilePath) {
- d->m_offlineAssetsFilePath = offlineAssetsFilePath;
- emit offlineAssetsFilePathChanged(d->m_offlineAssetsFilePath);
- }
-}
-
-QString AssetDownloader::jsonFileName() const
-{
- return d->m_jsonFileName;
-}
-
-void AssetDownloader::setJsonFileName(const QString &jsonFileName)
-{
- if (d->m_jsonFileName != jsonFileName) {
- d->m_jsonFileName = jsonFileName;
- emit jsonFileNameChanged(d->m_jsonFileName);
- }
-}
-
-QString AssetDownloader::zipFileName() const
-{
- return d->m_zipFileName;
-}
-
-void AssetDownloader::setZipFileName(const QString &zipFileName)
-{
- if (d->m_zipFileName != zipFileName) {
- d->m_zipFileName = zipFileName;
- emit zipFileNameChanged(d->m_zipFileName);
- }
-}
-
-QUrl AssetDownloader::localDownloadDir() const
-{
- return QUrl::fromLocalFile(d->m_localDownloadDir.absolutePath());
-}
-
-QStringList AssetDownloader::networkErrors() const
-{
- return d->m_networkErrors;
-}
-
-QStringList AssetDownloader::sslErrors() const
-{
- return d->m_sslErrors;
-}
-
-static void precheckLocalFile(const QUrl &url)
-{
- if (url.isEmpty())
- return;
- QFile file(pathFromUrl(url));
- if (!file.open(QIODevice::ReadOnly))
- qWarning() << "Cannot open local file" << url;
-}
-
-static void readAssetsFileContent(QPromise<DownloadableAssets> &promise, const QByteArray &content)
-{
- const QJsonObject json = QJsonDocument::fromJson(content).object();
- const QJsonArray assetsArray = json[u"assets"].toArray();
- DownloadableAssets result;
- result.remoteUrl = json[u"url"].toString();
- for (const QJsonValue &asset : assetsArray) {
- if (promise.isCanceled())
- return;
- result.files.append(asset.toString());
- }
-
- if (result.files.isEmpty() || result.remoteUrl.isEmpty())
- promise.future().cancel();
- else
- promise.addResult(result);
-}
-
-static void unzip(QPromise<void> &promise, const QByteArray &content, const QDir &directory,
- const QString &fileName)
-{
- const QString zipFilePath = directory.absoluteFilePath(fileName);
- QFile zipFile(zipFilePath);
- if (!zipFile.open(QIODevice::WriteOnly)) {
- promise.future().cancel();
- return;
- }
- zipFile.write(content);
- zipFile.close();
-
- if (promise.isCanceled())
- return;
-
- QZipReader reader(zipFilePath);
- const bool extracted = reader.extractAll(directory.absolutePath());
- reader.close();
- if (extracted)
- QFile::remove(zipFilePath);
- else
- promise.future().cancel();
-}
-
-static void writeAsset(QPromise<void> &promise, const QByteArray &content, const QString &filePath)
-{
- const QFileInfo fileInfo(filePath);
- QFile file(fileInfo.absoluteFilePath());
- if (!createDirectory(fileInfo.dir()) || !file.open(QFile::WriteOnly)) {
- promise.future().cancel();
- return;
- }
-
- if (promise.isCanceled())
- return;
-
- file.write(content);
- file.close();
-}
-
-static void copyAndCheck(QPromise<void> &promise, const QString &sourcePath, const QString &destPath)
-{
- QFile sourceFile(sourcePath);
- QFile destFile(destPath);
- const QFileInfo sourceFileInfo(sourceFile.fileName());
- const QFileInfo destFileInfo(destFile.fileName());
-
- if (destFile.exists() && !destFile.remove()) {
- qWarning().noquote() << QString::fromLatin1("Unable to remove file \"%1\".")
- .arg(QFileInfo(destFile.fileName()).absoluteFilePath());
- promise.future().cancel();
- return;
- }
-
- if (!createDirectory(destFileInfo.absolutePath())) {
- qWarning().noquote() << QString::fromLatin1("Cannot create directory \"%1\".")
- .arg(destFileInfo.absolutePath());
- promise.future().cancel();
- return;
- }
-
- if (promise.isCanceled())
- return;
-
- if (!sourceFile.copy(destFile.fileName()) && !sameFileContent(sourceFileInfo, destFileInfo))
- promise.future().cancel();
-}
-
-void AssetDownloader::start()
-{
- if (d->m_taskTreeRunner.isRunning())
- return;
-
- struct StorageData
- {
- QDir tempDir;
- QByteArray jsonContent;
- DownloadableAssets assets;
- QList<QUrl> assetsToDownload;
- QByteArray zipContent;
- int doneCount = 0;
- };
-
- const Storage<StorageData> storage;
-
- const auto onSetup = [this, storage] {
- if (!d->m_manager)
- d->m_manager = std::make_unique<QNetworkAccessManager>();
- if (!d->m_temporaryDir)
- d->m_temporaryDir = std::make_unique<QTemporaryDir>();
- if (!d->m_temporaryDir->isValid()) {
- qWarning() << "Cannot create a temporary directory.";
- return SetupResult::StopWithError;
- }
- storage->tempDir = d->m_temporaryDir->path();
- d->setLocalDownloadDir(baseLocalDir(d->m_preferredLocalDownloadDir));
- d->m_networkErrors.clear();
- d->m_sslErrors.clear();
- precheckLocalFile(resolvedUrl(d->m_offlineAssetsFilePath));
- return SetupResult::Continue;
- };
-
- const auto onJsonDownloadSetup = [this](NetworkQuery &query) {
- query.setRequest(QNetworkRequest(d->m_downloadBase.resolved(d->m_jsonFileName)));
- d->setupDownload(&query, tr("Downloading JSON file..."));
- };
- const auto onJsonDownloadDone = [this, storage](const NetworkQuery &query, DoneWith result) {
- if (result == DoneWith::Success) {
- storage->jsonContent = query.reply()->readAll();
- return DoneResult::Success;
- }
- qWarning() << "Cannot download" << d->m_downloadBase.resolved(d->m_jsonFileName)
- << query.reply()->errorString();
- if (d->m_offlineAssetsFilePath.isEmpty()) {
- qWarning() << "Also there is no local file as a replacement";
- return DoneResult::Error;
- }
-
- QFile file(pathFromUrl(resolvedUrl(d->m_offlineAssetsFilePath)));
- if (!file.open(QIODevice::ReadOnly)) {
- qWarning() << "Also failed to open" << d->m_offlineAssetsFilePath;
- return DoneResult::Error;
- }
-
- storage->jsonContent = file.readAll();
- return DoneResult::Success;
- };
-
- const auto onReadAssetsFileSetup = [storage](ConcurrentCall<DownloadableAssets> &async) {
- async.setConcurrentCallData(readAssetsFileContent, storage->jsonContent);
- };
- const auto onReadAssetsFileDone = [storage](const ConcurrentCall<DownloadableAssets> &async) {
- storage->assets = async.result();
- storage->assetsToDownload = storage->assets.files;
- };
-
- const auto onSkipIfAllAssetsPresent = [this, storage] {
- return allAssetsPresent(storage->assets.files, d->m_localDownloadDir)
- ? SetupResult::StopWithSuccess : SetupResult::Continue;
- };
-
- const auto onZipDownloadSetup = [this, storage](NetworkQuery &query) {
- if (d->m_zipFileName.isEmpty())
- return SetupResult::StopWithSuccess;
-
- query.setRequest(QNetworkRequest(d->m_downloadBase.resolved(d->m_zipFileName)));
- d->setupDownload(&query, tr("Downloading zip file..."));
- return SetupResult::Continue;
- };
- const auto onZipDownloadDone = [storage](const NetworkQuery &query, DoneWith result) {
- if (result == DoneWith::Success)
- storage->zipContent = query.reply()->readAll();
- return DoneResult::Success; // Ignore zip download failure
- };
-
- const auto onUnzipSetup = [this, storage](ConcurrentCall<void> &async) {
- if (storage->zipContent.isEmpty())
- return SetupResult::StopWithSuccess;
-
- async.setConcurrentCallData(unzip, storage->zipContent, storage->tempDir, d->m_zipFileName);
- d->clearProgress(tr("Unzipping..."));
- return SetupResult::Continue;
- };
- const auto onUnzipDone = [storage](DoneWith result) {
- if (result == DoneWith::Success) {
- // Avoid downloading assets that are present in unzipped tree
- StorageData &storageData = *storage;
- storageData.assetsToDownload =
- filterDownloadableAssets(storageData.assets.files, storageData.tempDir);
- } else {
- qWarning() << "ZipFile failed";
- }
- return DoneResult::Success; // Ignore unzip failure
- };
-
- const LoopUntil downloadIterator([storage](int iteration) {
- return iteration < storage->assetsToDownload.count();
- });
-
- const Storage<QByteArray> assetStorage;
-
- const auto onAssetsDownloadGroupSetup = [this, storage] {
- d->setProgress(0, storage->assetsToDownload.size(), tr("Downloading assets..."));
- };
-
- const auto onAssetDownloadSetup = [this, storage, downloadIterator](NetworkQuery &query) {
- query.setNetworkAccessManager(d->m_manager.get());
- query.setRequest(QNetworkRequest(storage->assets.remoteUrl.resolved(
- storage->assetsToDownload.at(downloadIterator.iteration()))));
- };
- const auto onAssetDownloadDone = [assetStorage](const NetworkQuery &query, DoneWith result) {
- if (result == DoneWith::Success)
- *assetStorage = query.reply()->readAll();
- };
-
- const auto onAssetWriteSetup = [storage, downloadIterator, assetStorage](
- ConcurrentCall<void> &async) {
- const QString filePath = storage->tempDir.absoluteFilePath(
- storage->assetsToDownload.at(downloadIterator.iteration()).toString());
- async.setConcurrentCallData(writeAsset, *assetStorage, filePath);
- };
- const auto onAssetWriteDone = [this, storage](DoneWith result) {
- if (result != DoneWith::Success) {
- qWarning() << "Asset write failed";
- return;
- }
- StorageData &storageData = *storage;
- ++storageData.doneCount;
- d->updateProgress(storageData.doneCount, storageData.assetsToDownload.size());
- };
-
- const LoopUntil copyIterator([storage](int iteration) {
- return iteration < storage->assets.files.count();
- });
-
- const auto onAssetsCopyGroupSetup = [this, storage] {
- storage->doneCount = 0;
- d->setProgress(0, storage->assets.files.size(), tr("Copying assets..."));
- };
-
- const auto onAssetCopySetup = [this, storage, copyIterator](ConcurrentCall<void> &async) {
- const QString fileName = storage->assets.files.at(copyIterator.iteration()).toString();
- const QString sourcePath = storage->tempDir.absoluteFilePath(fileName);
- const QString destPath = d->m_localDownloadDir.absoluteFilePath(fileName);
- async.setConcurrentCallData(copyAndCheck, sourcePath, destPath);
- };
- const auto onAssetCopyDone = [this, storage] {
- StorageData &storageData = *storage;
- ++storageData.doneCount;
- d->updateProgress(storageData.doneCount, storageData.assets.files.size());
- };
-
- const auto onAssetsCopyGroupDone = [this, storage](DoneWith result) {
- if (result != DoneWith::Success) {
- d->setLocalDownloadDir(storage->tempDir);
- qWarning() << "Asset copy failed";
- return;
- }
- d->m_temporaryDir.reset();
- };
-
- const Group recipe {
- storage,
- onGroupSetup(onSetup),
- NetworkQueryTask(onJsonDownloadSetup, onJsonDownloadDone),
- ConcurrentCallTask<DownloadableAssets>(onReadAssetsFileSetup, onReadAssetsFileDone, CallDoneIf::Success),
- Group {
- onGroupSetup(onSkipIfAllAssetsPresent),
- NetworkQueryTask(onZipDownloadSetup, onZipDownloadDone),
- ConcurrentCallTask<void>(onUnzipSetup, onUnzipDone),
- For (downloadIterator) >> Do {
- parallelIdealThreadCountLimit,
- onGroupSetup(onAssetsDownloadGroupSetup),
- Group {
- assetStorage,
- NetworkQueryTask(onAssetDownloadSetup, onAssetDownloadDone),
- ConcurrentCallTask<void>(onAssetWriteSetup, onAssetWriteDone)
- }
- },
- For (copyIterator) >> Do {
- parallelIdealThreadCountLimit,
- onGroupSetup(onAssetsCopyGroupSetup),
- ConcurrentCallTask<void>(onAssetCopySetup, onAssetCopyDone, CallDoneIf::Success),
- onGroupDone(onAssetsCopyGroupDone)
- }
- }
- };
- d->m_taskTreeRunner.start(recipe, [this](TaskTree *) { emit started(); },
- [this](DoneWith result) { emit finished(result == DoneWith::Success); });
-}
-
-QUrl AssetDownloader::resolvedUrl(const QUrl &url) const
-{
- return url;
-}
-
-} // namespace Assets::Downloader
-
-QT_END_NAMESPACE
diff --git a/src/assets/downloader/assetdownloader.h b/src/assets/downloader/assetdownloader.h
deleted file mode 100644
index 3c9351ceafe..00000000000
--- a/src/assets/downloader/assetdownloader.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef ASSETDOWNLOADER_H
-#define ASSETDOWNLOADER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/QObject>
-#include <QtCore/QUrl>
-
-#include <memory>
-
-QT_BEGIN_NAMESPACE
-
-namespace Assets::Downloader {
-
-class AssetDownloaderPrivate;
-
-class AssetDownloader : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY(
- QUrl downloadBase
- READ downloadBase
- WRITE setDownloadBase
- NOTIFY downloadBaseChanged)
-
- Q_PROPERTY(
- QUrl preferredLocalDownloadDir
- READ preferredLocalDownloadDir
- WRITE setPreferredLocalDownloadDir
- NOTIFY preferredLocalDownloadDirChanged)
-
- Q_PROPERTY(
- QUrl offlineAssetsFilePath
- READ offlineAssetsFilePath
- WRITE setOfflineAssetsFilePath
- NOTIFY offlineAssetsFilePathChanged)
-
- Q_PROPERTY(
- QString jsonFileName
- READ jsonFileName
- WRITE setJsonFileName
- NOTIFY jsonFileNameChanged)
-
- Q_PROPERTY(
- QString zipFileName
- READ zipFileName
- WRITE setZipFileName
- NOTIFY zipFileNameChanged)
-
- Q_PROPERTY(
- QUrl localDownloadDir
- READ localDownloadDir
- NOTIFY localDownloadDirChanged)
-
-public:
- AssetDownloader(QObject *parent = nullptr);
- ~AssetDownloader();
-
- QUrl downloadBase() const;
- void setDownloadBase(const QUrl &downloadBase);
-
- QUrl preferredLocalDownloadDir() const;
- void setPreferredLocalDownloadDir(const QUrl &localDir);
-
- QUrl offlineAssetsFilePath() const;
- void setOfflineAssetsFilePath(const QUrl &offlineAssetsFilePath);
-
- QString jsonFileName() const;
- void setJsonFileName(const QString &jsonFileName);
-
- QString zipFileName() const;
- void setZipFileName(const QString &zipFileName);
-
- QUrl localDownloadDir() const;
-
- Q_INVOKABLE QStringList networkErrors() const;
- Q_INVOKABLE QStringList sslErrors() const;
-
-public Q_SLOTS:
- void start();
-
-protected:
- virtual QUrl resolvedUrl(const QUrl &url) const;
-
-Q_SIGNALS:
- void started();
- void finished(bool success);
- void progressChanged(int progressValue, int progressMaximum, const QString &progressText);
- void localDownloadDirChanged(const QUrl &url);
-
- void downloadBaseChanged(const QUrl &);
- void preferredLocalDownloadDirChanged(const QUrl &url);
- void offlineAssetsFilePathChanged(const QUrl &);
- void jsonFileNameChanged(const QString &);
- void zipFileNameChanged(const QString &);
-
-private:
- std::unique_ptr<AssetDownloaderPrivate> d;
-};
-
-} // namespace Assets::Downloader
-
-QT_END_NAMESPACE
-
-#endif // ASSETDOWNLOADER_H
diff --git a/src/assets/downloader/tasking/barrier.cpp b/src/assets/downloader/tasking/barrier.cpp
deleted file mode 100644
index c9e5992bc78..00000000000
--- a/src/assets/downloader/tasking/barrier.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "barrier.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-// That's cut down qtcassert.{c,h} to avoid the dependency.
-#define QT_STRING(cond) qDebug("SOFT ASSERT: \"%s\" in %s: %s", cond, __FILE__, QT_STRINGIFY(__LINE__))
-#define QT_ASSERT(cond, action) if (Q_LIKELY(cond)) {} else { QT_STRING(#cond); action; } do {} while (0)
-
-void Barrier::setLimit(int value)
-{
- QT_ASSERT(!isRunning(), return);
- QT_ASSERT(value > 0, return);
-
- m_limit = value;
-}
-
-void Barrier::start()
-{
- QT_ASSERT(!isRunning(), return);
- m_current = 0;
- m_result.reset();
-}
-
-void Barrier::advance()
-{
- // Calling advance on finished is OK
- QT_ASSERT(isRunning() || m_result, return);
- if (!isRunning()) // no-op
- return;
- ++m_current;
- if (m_current == m_limit)
- stopWithResult(DoneResult::Success);
-}
-
-void Barrier::stopWithResult(DoneResult result)
-{
- // Calling stopWithResult on finished is OK when the same success is passed
- QT_ASSERT(isRunning() || (m_result && *m_result == result), return);
- if (!isRunning()) // no-op
- return;
- m_current = -1;
- m_result = result;
- emit done(result);
-}
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
diff --git a/src/assets/downloader/tasking/barrier.h b/src/assets/downloader/tasking/barrier.h
deleted file mode 100644
index d489d2722a4..00000000000
--- a/src/assets/downloader/tasking/barrier.h
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_BARRIER_H
-#define TASKING_BARRIER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasking_global.h"
-
-#include "tasktree.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-class TASKING_EXPORT Barrier final : public QObject
-{
- Q_OBJECT
-
-public:
- void setLimit(int value);
- int limit() const { return m_limit; }
-
- void start();
- void advance(); // If limit reached, stops with true
- void stopWithResult(DoneResult result); // Ignores limit
-
- bool isRunning() const { return m_current >= 0; }
- int current() const { return m_current; }
- std::optional<DoneResult> result() const { return m_result; }
-
-Q_SIGNALS:
- void done(DoneResult success);
-
-private:
- std::optional<DoneResult> m_result = {};
- int m_limit = 1;
- int m_current = -1;
-};
-
-using BarrierTask = SimpleCustomTask<Barrier>;
-
-template <int Limit = 1>
-class SharedBarrier
-{
-public:
- static_assert(Limit > 0, "SharedBarrier's limit should be 1 or more.");
- SharedBarrier() : m_barrier(new Barrier) {
- m_barrier->setLimit(Limit);
- m_barrier->start();
- }
- Barrier *barrier() const { return m_barrier.get(); }
-
-private:
- std::shared_ptr<Barrier> m_barrier;
-};
-
-template <int Limit = 1>
-using MultiBarrier = Storage<SharedBarrier<Limit>>;
-
-// Can't write: "MultiBarrier barrier;". Only "MultiBarrier<> barrier;" would work.
-// Can't have one alias with default type in C++17, getting the following error:
-// alias template deduction only available with C++20.
-using SingleBarrier = MultiBarrier<1>;
-
-template <int Limit>
-ExecutableItem waitForBarrierTask(const MultiBarrier<Limit> &sharedBarrier)
-{
- return BarrierTask([sharedBarrier](Barrier &barrier) {
- SharedBarrier<Limit> *activeBarrier = sharedBarrier.activeStorage();
- if (!activeBarrier) {
- qWarning("The barrier referenced from WaitForBarrier element "
- "is not reachable in the running tree. "
- "It is possible that no barrier was added to the tree, "
- "or the barrier is not reachable from where it is referenced. "
- "The WaitForBarrier task finishes with an error. ");
- return SetupResult::StopWithError;
- }
- Barrier *activeSharedBarrier = activeBarrier->barrier();
- const std::optional<DoneResult> result = activeSharedBarrier->result();
- if (result.has_value()) {
- return *result == DoneResult::Success ? SetupResult::StopWithSuccess
- : SetupResult::StopWithError;
- }
- QObject::connect(activeSharedBarrier, &Barrier::done, &barrier, &Barrier::stopWithResult);
- return SetupResult::Continue;
- });
-}
-
-template <typename Signal>
-ExecutableItem signalAwaiter(const typename QtPrivate::FunctionPointer<Signal>::Object *sender, Signal signal)
-{
- return BarrierTask([sender, signal](Barrier &barrier) {
- QObject::connect(sender, signal, &barrier, &Barrier::advance, Qt::SingleShotConnection);
- });
-}
-
-using BarrierKickerGetter = std::function<ExecutableItem(const SingleBarrier &)>;
-
-class TASKING_EXPORT When final
-{
-public:
- explicit When(const BarrierKickerGetter &kicker) : m_barrierKicker(kicker) {}
-
-private:
- TASKING_EXPORT friend Group operator>>(const When &whenItem, const Do &doItem);
-
- BarrierKickerGetter m_barrierKicker;
-};
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
-
-#endif // TASKING_BARRIER_H
diff --git a/src/assets/downloader/tasking/concurrentcall.h b/src/assets/downloader/tasking/concurrentcall.h
deleted file mode 100644
index cc701297d13..00000000000
--- a/src/assets/downloader/tasking/concurrentcall.h
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_CONCURRENTCALL_H
-#define TASKING_CONCURRENTCALL_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasktree.h"
-
-#include <QtConcurrent/QtConcurrent>
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-// This class introduces the dependency to Qt::Concurrent, otherwise Tasking namespace
-// is independent on Qt::Concurrent.
-// Possibly, it could be placed inside Qt::Concurrent library, as a wrapper around
-// QtConcurrent::run() call.
-
-template <typename ResultType>
-class ConcurrentCall
-{
- Q_DISABLE_COPY_MOVE(ConcurrentCall)
-
-public:
- ConcurrentCall() = default;
- template <typename Function, typename ...Args>
- void setConcurrentCallData(Function &&function, Args &&...args)
- {
- wrapConcurrent(std::forward<Function>(function), std::forward<Args>(args)...);
- }
- void setThreadPool(QThreadPool *pool) { m_threadPool = pool; }
- ResultType result() const
- {
- return m_future.resultCount() ? m_future.result() : ResultType();
- }
- QList<ResultType> results() const
- {
- return m_future.results();
- }
- QFuture<ResultType> future() const { return m_future; }
-
-private:
- template <typename Function, typename ...Args>
- void wrapConcurrent(Function &&function, Args &&...args)
- {
- m_startHandler = [this, function = std::forward<Function>(function), args...] {
- QThreadPool *threadPool = m_threadPool ? m_threadPool : QThreadPool::globalInstance();
- return QtConcurrent::run(threadPool, function, args...);
- };
- }
-
- template <typename Function, typename ...Args>
- void wrapConcurrent(std::reference_wrapper<const Function> &&wrapper, Args &&...args)
- {
- m_startHandler = [this, wrapper = std::forward<std::reference_wrapper<const Function>>(wrapper), args...] {
- QThreadPool *threadPool = m_threadPool ? m_threadPool : QThreadPool::globalInstance();
- return QtConcurrent::run(threadPool, std::forward<const Function>(wrapper.get()),
- args...);
- };
- }
-
- template <typename T>
- friend class ConcurrentCallTaskAdapter;
-
- std::function<QFuture<ResultType>()> m_startHandler;
- QThreadPool *m_threadPool = nullptr;
- QFuture<ResultType> m_future;
-};
-
-template <typename ResultType>
-class ConcurrentCallTaskAdapter : public TaskAdapter<ConcurrentCall<ResultType>>
-{
-public:
- ~ConcurrentCallTaskAdapter() {
- if (m_watcher) {
- m_watcher->cancel();
- m_watcher->waitForFinished();
- }
- }
-
- void start() final {
- if (!this->task()->m_startHandler) {
- emit this->done(DoneResult::Error); // TODO: Add runtime assert
- return;
- }
- m_watcher.reset(new QFutureWatcher<ResultType>);
- this->connect(m_watcher.get(), &QFutureWatcherBase::finished, this, [this] {
- emit this->done(toDoneResult(!m_watcher->isCanceled()));
- m_watcher.release()->deleteLater();
- });
- this->task()->m_future = this->task()->m_startHandler();
- m_watcher->setFuture(this->task()->m_future);
- }
-
-private:
- std::unique_ptr<QFutureWatcher<ResultType>> m_watcher;
-};
-
-template <typename T>
-using ConcurrentCallTask = CustomTask<ConcurrentCallTaskAdapter<T>>;
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
-
-#endif // TASKING_CONCURRENTCALL_H
diff --git a/src/assets/downloader/tasking/conditional.cpp b/src/assets/downloader/tasking/conditional.cpp
deleted file mode 100644
index 24a03fb703e..00000000000
--- a/src/assets/downloader/tasking/conditional.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "conditional.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-static Group conditionRecipe(const Storage<bool> &bodyExecutedStorage, const ConditionData &condition)
-{
- const auto onSetup = [bodyExecutedStorage] {
- return *bodyExecutedStorage ? SetupResult::StopWithSuccess : SetupResult::Continue;
- };
-
- const auto onBodyDone = [bodyExecutedStorage] { *bodyExecutedStorage = true; };
-
- const Group bodyTask { condition.m_body, onGroupDone(onBodyDone) };
-
- return {
- onGroupSetup(onSetup),
- condition.m_condition ? Group{ !*condition.m_condition || bodyTask } : bodyTask
- };
-}
-
-static ExecutableItem conditionsRecipe(const QList<ConditionData> &conditions)
-{
- Storage<bool> bodyExecutedStorage;
-
- GroupItems recipes;
- for (const ConditionData &condition : conditions)
- recipes << conditionRecipe(bodyExecutedStorage, condition);
-
- return Group { bodyExecutedStorage, recipes };
-}
-
-ThenItem::operator ExecutableItem() const
-{
- return conditionsRecipe(m_conditions);
-}
-
-ThenItem::ThenItem(const If &ifItem, const Then &thenItem)
- : m_conditions{{ifItem.m_condition, thenItem.m_body}}
-{}
-
-ThenItem::ThenItem(const ElseIfItem &elseIfItem, const Then &thenItem)
- : m_conditions(elseIfItem.m_conditions)
-{
- m_conditions.append({elseIfItem.m_nextCondition, thenItem.m_body});
-}
-
-ElseItem::operator ExecutableItem() const
-{
- return conditionsRecipe(m_conditions);
-}
-
-ElseItem::ElseItem(const ThenItem &thenItem, const Else &elseItem)
- : m_conditions(thenItem.m_conditions)
-{
- m_conditions.append({{}, elseItem.m_body});
-}
-
-ElseIfItem::ElseIfItem(const ThenItem &thenItem, const ElseIf &elseIfItem)
- : m_conditions(thenItem.m_conditions)
- , m_nextCondition(elseIfItem.m_condition)
-{}
-
-ThenItem operator>>(const If &ifItem, const Then &thenItem)
-{
- return {ifItem, thenItem};
-}
-
-ThenItem operator>>(const ElseIfItem &elseIfItem, const Then &thenItem)
-{
- return {elseIfItem, thenItem};
-}
-
-ElseIfItem operator>>(const ThenItem &thenItem, const ElseIf &elseIfItem)
-{
- return {thenItem, elseIfItem};
-}
-
-ElseItem operator>>(const ThenItem &thenItem, const Else &elseItem)
-{
- return {thenItem, elseItem};
-}
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
diff --git a/src/assets/downloader/tasking/conditional.h b/src/assets/downloader/tasking/conditional.h
deleted file mode 100644
index 52fdfd64cb7..00000000000
--- a/src/assets/downloader/tasking/conditional.h
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_CONDITIONAL_H
-#define TASKING_CONDITIONAL_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasking_global.h"
-
-#include "tasktree.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-class Then;
-class ThenItem;
-class ElseItem;
-class ElseIfItem;
-
-class TASKING_EXPORT If
-{
-public:
- explicit If(const ExecutableItem &condition) : m_condition(condition) {}
-
- template <typename Handler,
- std::enable_if_t<!std::is_base_of_v<ExecutableItem, std::decay_t<Handler>>, bool> = true>
- explicit If(Handler &&handler) : m_condition(Sync(std::forward<Handler>(handler))) {}
-
-private:
- TASKING_EXPORT friend ThenItem operator>>(const If &ifItem, const Then &thenItem);
-
- friend class ThenItem;
- ExecutableItem m_condition;
-};
-
-class TASKING_EXPORT ElseIf
-{
-public:
- explicit ElseIf(const ExecutableItem &condition) : m_condition(condition) {}
-
- template <typename Handler,
- std::enable_if_t<!std::is_base_of_v<ExecutableItem, std::decay_t<Handler>>, bool> = true>
- explicit ElseIf(Handler &&handler) : m_condition(Sync(std::forward<Handler>(handler))) {}
-
-private:
- friend class ElseIfItem;
- ExecutableItem m_condition;
-};
-
-class TASKING_EXPORT Else
-{
-public:
- explicit Else(const GroupItems &children) : m_body({children}) {}
- explicit Else(std::initializer_list<GroupItem> children) : m_body({children}) {}
-
-private:
- friend class ElseItem;
- Group m_body;
-};
-
-class TASKING_EXPORT Then
-{
-public:
- explicit Then(const GroupItems &children) : m_body({children}) {}
- explicit Then(std::initializer_list<GroupItem> children) : m_body({children}) {}
-
-private:
- friend class ThenItem;
- Group m_body;
-};
-
-class ConditionData
-{
-public:
- std::optional<ExecutableItem> m_condition;
- Group m_body;
-};
-
-class ElseIfItem;
-
-class TASKING_EXPORT ThenItem
-{
-public:
- operator ExecutableItem() const;
-
-private:
- ThenItem(const If &ifItem, const Then &thenItem);
- ThenItem(const ElseIfItem &elseIfItem, const Then &thenItem);
-
- TASKING_EXPORT friend ElseItem operator>>(const ThenItem &thenItem, const Else &elseItem);
- TASKING_EXPORT friend ElseIfItem operator>>(const ThenItem &thenItem, const ElseIf &elseIfItem);
- TASKING_EXPORT friend ThenItem operator>>(const If &ifItem, const Then &thenItem);
- TASKING_EXPORT friend ThenItem operator>>(const ElseIfItem &elseIfItem, const Then &thenItem);
-
- friend class ElseItem;
- friend class ElseIfItem;
- QList<ConditionData> m_conditions;
-};
-
-class TASKING_EXPORT ElseItem
-{
-public:
- operator ExecutableItem() const;
-
-private:
- ElseItem(const ThenItem &thenItem, const Else &elseItem);
-
- TASKING_EXPORT friend ElseItem operator>>(const ThenItem &thenItem, const Else &elseItem);
-
- QList<ConditionData> m_conditions;
-};
-
-class TASKING_EXPORT ElseIfItem
-{
-private:
- ElseIfItem(const ThenItem &thenItem, const ElseIf &elseIfItem);
-
- TASKING_EXPORT friend ThenItem operator>>(const ElseIfItem &elseIfItem, const Then &thenItem);
- TASKING_EXPORT friend ElseIfItem operator>>(const ThenItem &thenItem, const ElseIf &elseIfItem);
-
- friend class ThenItem;
- QList<ConditionData> m_conditions;
- ExecutableItem m_nextCondition;
-};
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
-
-#endif // TASKING_CONDITIONAL_H
diff --git a/src/assets/downloader/tasking/networkquery.cpp b/src/assets/downloader/tasking/networkquery.cpp
deleted file mode 100644
index 3f15fed90e0..00000000000
--- a/src/assets/downloader/tasking/networkquery.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "networkquery.h"
-
-#include <QtNetwork/QNetworkAccessManager>
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-void NetworkQuery::start()
-{
- if (m_reply) {
- qWarning("The NetworkQuery is already running. Ignoring the call to start().");
- return;
- }
- if (!m_manager) {
- qWarning("Can't start the NetworkQuery without the QNetworkAccessManager. "
- "Stopping with an error.");
- emit done(DoneResult::Error);
- return;
- }
- switch (m_operation) {
- case NetworkOperation::Get:
- m_reply.reset(m_manager->get(m_request));
- break;
- case NetworkOperation::Put:
- m_reply.reset(m_manager->put(m_request, m_writeData));
- break;
- case NetworkOperation::Post:
- m_reply.reset(m_manager->post(m_request, m_writeData));
- break;
- case NetworkOperation::Delete:
- m_reply.reset(m_manager->deleteResource(m_request));
- break;
- }
-
- connect(m_reply.get(), &QNetworkReply::downloadProgress, this, &NetworkQuery::downloadProgress);
-#if QT_CONFIG(ssl)
- connect(m_reply.get(), &QNetworkReply::sslErrors, this, &NetworkQuery::sslErrors);
-#endif
- connect(m_reply.get(), &QNetworkReply::finished, this, [this] {
- disconnect(m_reply.get(), &QNetworkReply::finished, this, nullptr);
- emit done(toDoneResult(m_reply->error() == QNetworkReply::NoError));
- m_reply.release()->deleteLater();
- });
- if (m_reply->isRunning())
- emit started();
-}
-
-NetworkQuery::~NetworkQuery()
-{
- if (m_reply) {
- disconnect(m_reply.get(), nullptr, this, nullptr);
- m_reply->abort();
- }
-}
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
diff --git a/src/assets/downloader/tasking/networkquery.h b/src/assets/downloader/tasking/networkquery.h
deleted file mode 100644
index 2733fef8352..00000000000
--- a/src/assets/downloader/tasking/networkquery.h
+++ /dev/null
@@ -1,74 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_NETWORKQUERY_H
-#define TASKING_NETWORKQUERY_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasking_global.h"
-
-#include "tasktree.h"
-
-#include <QtNetwork/QNetworkReply>
-#include <QtNetwork/QNetworkRequest>
-
-#include <memory>
-
-QT_BEGIN_NAMESPACE
-class QNetworkAccessManager;
-
-namespace Tasking {
-
-// This class introduces the dependency to Qt::Network, otherwise Tasking namespace
-// is independent on Qt::Network.
-// Possibly, it could be placed inside Qt::Network library, as a wrapper around QNetworkReply.
-
-enum class NetworkOperation { Get, Put, Post, Delete };
-
-class TASKING_EXPORT NetworkQuery final : public QObject
-{
- Q_OBJECT
-
-public:
- ~NetworkQuery();
- void setRequest(const QNetworkRequest &request) { m_request = request; }
- void setOperation(NetworkOperation operation) { m_operation = operation; }
- void setWriteData(const QByteArray &data) { m_writeData = data; }
- void setNetworkAccessManager(QNetworkAccessManager *manager) { m_manager = manager; }
- QNetworkReply *reply() const { return m_reply.get(); }
- void start();
-
-Q_SIGNALS:
- void started();
- void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
-#if QT_CONFIG(ssl)
- void sslErrors(const QList<QSslError> &errors);
-#endif
- void done(DoneResult result);
-
-private:
- QNetworkRequest m_request;
- NetworkOperation m_operation = NetworkOperation::Get;
- QByteArray m_writeData; // Used by Put and Post
- QNetworkAccessManager *m_manager = nullptr;
- std::unique_ptr<QNetworkReply> m_reply;
-};
-
-using NetworkQueryTask = SimpleCustomTask<NetworkQuery>;
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
-
-#endif // TASKING_NETWORKQUERY_H
diff --git a/src/assets/downloader/tasking/qprocesstask.cpp b/src/assets/downloader/tasking/qprocesstask.cpp
deleted file mode 100644
index a4696ebbbfb..00000000000
--- a/src/assets/downloader/tasking/qprocesstask.cpp
+++ /dev/null
@@ -1,280 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "qprocesstask.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QDebug>
-#include <QtCore/QElapsedTimer>
-#include <QtCore/QMutex>
-#include <QtCore/QThread>
-#include <QtCore/QTimer>
-#include <QtCore/QWaitCondition>
-
-QT_BEGIN_NAMESPACE
-
-#if QT_CONFIG(process)
-
-namespace Tasking {
-
-class ProcessReaperPrivate;
-
-class ProcessReaper final
-{
-public:
- static void reap(QProcess *process, int timeoutMs = 500);
- ProcessReaper();
- ~ProcessReaper();
-
-private:
- static ProcessReaper *instance();
-
- QThread m_thread;
- ProcessReaperPrivate *m_private;
-};
-
-static const int s_timeoutThreshold = 10000; // 10 seconds
-
-static QString execWithArguments(QProcess *process)
-{
- QStringList commandLine;
- commandLine.append(process->program());
- commandLine.append(process->arguments());
- return commandLine.join(QChar::Space);
-}
-
-struct ReaperSetup
-{
- QProcess *m_process = nullptr;
- int m_timeoutMs;
-};
-
-class Reaper : public QObject
-{
- Q_OBJECT
-
-public:
- Reaper(const ReaperSetup &reaperSetup) : m_reaperSetup(reaperSetup) {}
-
- void reap()
- {
- m_timer.start();
- connect(m_reaperSetup.m_process, &QProcess::finished, this, &Reaper::handleFinished);
- if (emitFinished())
- return;
- terminate();
- }
-
-Q_SIGNALS:
- void finished();
-
-private:
- void terminate()
- {
- m_reaperSetup.m_process->terminate();
- QTimer::singleShot(m_reaperSetup.m_timeoutMs, this, &Reaper::handleTerminateTimeout);
- }
-
- void kill() { m_reaperSetup.m_process->kill(); }
-
- bool emitFinished()
- {
- if (m_reaperSetup.m_process->state() != QProcess::NotRunning)
- return false;
-
- if (!m_finished) {
- const int timeout = m_timer.elapsed();
- if (timeout > s_timeoutThreshold) {
- qWarning() << "Finished parallel reaping of" << execWithArguments(m_reaperSetup.m_process)
- << "in" << (timeout / 1000.0) << "seconds.";
- }
-
- m_finished = true;
- emit finished();
- }
- return true;
- }
-
- void handleFinished()
- {
- if (emitFinished())
- return;
- qWarning() << "Finished process still running...";
- // In case the process is still running - wait until it has finished
- QTimer::singleShot(m_reaperSetup.m_timeoutMs, this, &Reaper::handleFinished);
- }
-
- void handleTerminateTimeout()
- {
- if (emitFinished())
- return;
- kill();
- }
-
- bool m_finished = false;
- QElapsedTimer m_timer;
- const ReaperSetup m_reaperSetup;
-};
-
-class ProcessReaperPrivate : public QObject
-{
- Q_OBJECT
-
-public:
- // Called from non-reaper's thread
- void scheduleReap(const ReaperSetup &reaperSetup)
- {
- if (QThread::currentThread() == thread())
- qWarning() << "Can't schedule reap from the reaper internal thread.";
-
- QMutexLocker locker(&m_mutex);
- m_reaperSetupList.append(reaperSetup);
- QMetaObject::invokeMethod(this, &ProcessReaperPrivate::flush);
- }
-
- // Called from non-reaper's thread
- void waitForFinished()
- {
- if (QThread::currentThread() == thread())
- qWarning() << "Can't wait for finished from the reaper internal thread.";
-
- QMetaObject::invokeMethod(this, &ProcessReaperPrivate::flush,
- Qt::BlockingQueuedConnection);
- QMutexLocker locker(&m_mutex);
- if (m_reaperList.isEmpty())
- return;
-
- m_waitCondition.wait(&m_mutex);
- }
-
-private:
- // All the private methods are called from the reaper's thread
- QList<ReaperSetup> takeReaperSetupList()
- {
- QMutexLocker locker(&m_mutex);
- return std::exchange(m_reaperSetupList, {});
- }
-
- void flush()
- {
- while (true) {
- const QList<ReaperSetup> reaperSetupList = takeReaperSetupList();
- if (reaperSetupList.isEmpty())
- return;
- for (const ReaperSetup &reaperSetup : reaperSetupList)
- reap(reaperSetup);
- }
- }
-
- void reap(const ReaperSetup &reaperSetup)
- {
- Reaper *reaper = new Reaper(reaperSetup);
- connect(reaper, &Reaper::finished, this, [this, reaper, process = reaperSetup.m_process] {
- QMutexLocker locker(&m_mutex);
- const bool isRemoved = m_reaperList.removeOne(reaper);
- if (!isRemoved)
- qWarning() << "Reaper list doesn't contain the finished process.";
-
- delete reaper;
- delete process;
- if (m_reaperList.isEmpty())
- m_waitCondition.wakeOne();
- }, Qt::QueuedConnection);
-
- {
- QMutexLocker locker(&m_mutex);
- m_reaperList.append(reaper);
- }
-
- reaper->reap();
- }
-
- QMutex m_mutex;
- QWaitCondition m_waitCondition;
- QList<ReaperSetup> m_reaperSetupList;
- QList<Reaper *> m_reaperList;
-};
-
-static ProcessReaper *s_instance = nullptr;
-static QMutex s_instanceMutex;
-
-// Call me with s_instanceMutex locked.
-ProcessReaper *ProcessReaper::instance()
-{
- if (!s_instance)
- s_instance = new ProcessReaper;
- return s_instance;
-}
-
-ProcessReaper::ProcessReaper()
- : m_private(new ProcessReaperPrivate)
-{
- m_private->moveToThread(&m_thread);
- QObject::connect(&m_thread, &QThread::finished, m_private, &QObject::deleteLater);
- m_thread.start();
- m_thread.moveToThread(qApp->thread());
-}
-
-ProcessReaper::~ProcessReaper()
-{
- if (!QThread::isMainThread())
- qWarning() << "Destructing process reaper from non-main thread.";
-
- instance()->m_private->waitForFinished();
- m_thread.quit();
- m_thread.wait();
-}
-
-void ProcessReaper::reap(QProcess *process, int timeoutMs)
-{
- if (!process)
- return;
-
- if (QThread::currentThread() != process->thread()) {
- qWarning() << "Can't reap process from non-process's thread.";
- return;
- }
-
- process->disconnect();
- if (process->state() == QProcess::NotRunning) {
- delete process;
- return;
- }
-
- // Neither can move object with a parent into a different thread
- // nor reaping the process with a parent makes any sense.
- process->setParent(nullptr);
-
- QMutexLocker locker(&s_instanceMutex);
- ProcessReaperPrivate *priv = instance()->m_private;
-
- process->moveToThread(priv->thread());
- ReaperSetup reaperSetup {process, timeoutMs};
- priv->scheduleReap(reaperSetup);
-}
-
-void QProcessDeleter::deleteAll()
-{
- QMutexLocker locker(&s_instanceMutex);
- delete s_instance;
- s_instance = nullptr;
-}
-
-void QProcessDeleter::operator()(QProcess *process)
-{
- ProcessReaper::reap(process);
-}
-
-} // namespace Tasking
-
-#endif // QT_CONFIG(process)
-
-QT_END_NAMESPACE
-
-#if QT_CONFIG(process)
-
-#include "qprocesstask.moc"
-
-#endif // QT_CONFIG(process)
-
diff --git a/src/assets/downloader/tasking/qprocesstask.h b/src/assets/downloader/tasking/qprocesstask.h
deleted file mode 100644
index 6f2ca4a18e2..00000000000
--- a/src/assets/downloader/tasking/qprocesstask.h
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_QPROCESSTASK_H
-#define TASKING_QPROCESSTASK_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasking_global.h"
-
-#include "tasktree.h"
-
-#include <QtCore/QProcess>
-
-QT_BEGIN_NAMESPACE
-
-#if QT_CONFIG(process)
-
-namespace Tasking {
-
-// Deleting a running QProcess may block the caller thread up to 30 seconds and issue warnings.
-// To avoid these issues we move the running QProcess into a separate thread
-// managed by the internal ProcessReaper, instead of deleting it immediately.
-// Inside the ProcessReaper's thread we try to finish the process in a most gentle way:
-// we call QProcess::terminate() with 500 ms timeout, and if the process is still running
-// after this timeout passed, we call QProcess::kill() and wait for the process to finish.
-// All these handlings are done is a separate thread, so the main thread doesn't block at all
-// when the QProcessTask is destructed.
-// Finally, on application quit, QProcessDeleter::deleteAll() should be called in order
-// to synchronize all the processes being still potentially reaped in a separate thread.
-// The call to QProcessDeleter::deleteAll() is blocking in case some processes
-// are still being reaped.
-// This strategy seems most sensible, since when passing the running QProcess into the
-// ProcessReaper we don't block immediately, but postpone the possible (not certain) block
-// until the end of an application.
-// In this way we terminate the running processes in the most safe way and keep the main thread
-// responsive. That's a common case when the running application wants to terminate the QProcess
-// immediately (e.g. on Cancel button pressed), without keeping and managing the handle
-// to the still running QProcess.
-
-// The implementation of the internal reaper is inspired by the Utils::ProcessReaper taken
-// from the QtCreator codebase.
-
-class TASKING_EXPORT QProcessDeleter
-{
-public:
- // Blocking, should be called after all QProcessAdapter instances are deleted.
- static void deleteAll();
- void operator()(QProcess *process);
-};
-
-class TASKING_EXPORT QProcessAdapter : public TaskAdapter<QProcess, QProcessDeleter>
-{
-private:
- void start() final {
- connect(task(), &QProcess::finished, this, [this] {
- const bool success = task()->exitStatus() == QProcess::NormalExit
- && task()->error() == QProcess::UnknownError
- && task()->exitCode() == 0;
- Q_EMIT done(toDoneResult(success));
- });
- connect(task(), &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) {
- if (error != QProcess::FailedToStart)
- return;
- Q_EMIT done(DoneResult::Error);
- });
- task()->start();
- }
-};
-
-using QProcessTask = CustomTask<QProcessAdapter>;
-
-} // namespace Tasking
-
-#endif // QT_CONFIG(process)
-
-QT_END_NAMESPACE
-
-#endif // TASKING_QPROCESSTASK_H
diff --git a/src/assets/downloader/tasking/tasking_global.h b/src/assets/downloader/tasking/tasking_global.h
deleted file mode 100644
index 57f0b7fefef..00000000000
--- a/src/assets/downloader/tasking/tasking_global.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_GLOBAL_H
-#define TASKING_GLOBAL_H
-
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_NAMESPACE
-
-// #if defined(QT_SHARED) || !defined(QT_STATIC)
-// # if defined(TASKING_LIBRARY)
-// # define TASKING_EXPORT Q_DECL_EXPORT
-// # else
-// # define TASKING_EXPORT Q_DECL_IMPORT
-// # endif
-// #else
-// # define TASKING_EXPORT
-// #endif
-
-#define TASKING_EXPORT
-
-QT_END_NAMESPACE
-
-#endif // TASKING_GLOBAL_H
diff --git a/src/assets/downloader/tasking/tasktree.cpp b/src/assets/downloader/tasking/tasktree.cpp
deleted file mode 100644
index 37064a3e714..00000000000
--- a/src/assets/downloader/tasking/tasktree.cpp
+++ /dev/null
@@ -1,3701 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "tasktree.h"
-
-#include "barrier.h"
-#include "conditional.h"
-
-#include <QtCore/QDebug>
-#include <QtCore/QEventLoop>
-#include <QtCore/QFutureWatcher>
-#include <QtCore/QHash>
-#include <QtCore/QMetaEnum>
-#include <QtCore/QMutex>
-#include <QtCore/QPointer>
-#include <QtCore/QPromise>
-#include <QtCore/QSet>
-#include <QtCore/QTime>
-#include <QtCore/QTimer>
-
-using namespace Qt::StringLiterals;
-using namespace std::chrono;
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-// That's cut down qtcassert.{c,h} to avoid the dependency.
-#define QT_STRING(cond) qDebug("SOFT ASSERT: \"%s\" in %s: %s", cond, __FILE__, QT_STRINGIFY(__LINE__))
-#define QT_ASSERT(cond, action) if (Q_LIKELY(cond)) {} else { QT_STRING(#cond); action; } do {} while (0)
-#define QT_CHECK(cond) if (cond) {} else { QT_STRING(#cond); } do {} while (0)
-
-class Guard
-{
- Q_DISABLE_COPY(Guard)
-public:
- Guard() = default;
- ~Guard() { QT_CHECK(m_lockCount == 0); }
- bool isLocked() const { return m_lockCount; }
-private:
- int m_lockCount = 0;
- friend class GuardLocker;
-};
-
-class GuardLocker
-{
- Q_DISABLE_COPY(GuardLocker)
-public:
- GuardLocker(Guard &guard) : m_guard(guard) { ++m_guard.m_lockCount; }
- ~GuardLocker() { --m_guard.m_lockCount; }
-private:
- Guard &m_guard;
-};
-
-/*!
- \module TaskingSolution
- \title Tasking Solution
- \ingroup solutions-modules
- \brief Contains a general purpose Tasking solution.
-
- The Tasking solution depends on Qt only, and doesn't depend on any \QC specific code.
-*/
-
-/*!
- \namespace Tasking
- \inmodule TaskingSolution
- \brief The Tasking namespace encloses all classes and global functions of the Tasking solution.
-*/
-
-/*!
- \class Tasking::TaskInterface
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief TaskInterface is the abstract base class for implementing custom task adapters.
- \reentrant
-
- To implement a custom task adapter, derive your adapter from the
- \c TaskAdapter<Task> class template. TaskAdapter automatically creates and destroys
- the custom task instance and associates the adapter with a given \c Task type.
-*/
-
-/*!
- \fn virtual void TaskInterface::start()
-
- This method is called by the running TaskTree for starting the \c Task instance.
- Reimplement this method in \c TaskAdapter<Task>'s subclass in order to start the
- associated task.
-
- Use TaskAdapter::task() to access the associated \c Task instance.
-
- \sa done(), TaskAdapter::task()
-*/
-
-/*!
- \fn void TaskInterface::done(DoneResult result)
-
- Emit this signal from the \c TaskAdapter<Task>'s subclass, when the \c Task is finished.
- Pass DoneResult::Success as a \a result argument when the task finishes with success;
- otherwise, when an error occurs, pass DoneResult::Error.
-*/
-
-/*!
- \class Tasking::TaskAdapter
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief A class template for implementing custom task adapters.
- \reentrant
-
- The TaskAdapter class template is responsible for creating a task of the \c Task type,
- starting it, and reporting success or an error when the task is finished.
- It also associates the adapter with a given \c Task type.
-
- Reimplement this class with the actual \c Task type to adapt the task's interface
- into the general TaskTree's interface for managing the \c Task instances.
-
- Each subclass needs to provide a public default constructor,
- implement the start() method, and emit the done() signal when the task is finished.
- Use task() to access the associated \c Task instance.
-
- To use your task adapter inside the task tree, create an alias to the
- Tasking::CustomTask template passing your task adapter as a template parameter:
- \code
- // Defines actual worker
- class Worker {...};
-
- // Adapts Worker's interface to work with task tree
- class WorkerTaskAdapter : public TaskAdapter<Worker> {...};
-
- // Defines WorkerTask as a new custom task type to be placed inside Group items
- using WorkerTask = CustomTask<WorkerTaskAdapter>;
- \endcode
-
- Optionally, you may pass a custom \c Deleter for the associated \c Task
- as a second template parameter of your \c TaskAdapter subclass.
- When the \c Deleter parameter is omitted, the \c std::default_delete<Task> is used by default.
- The custom \c Deleter is useful when the destructor of the running \c Task
- may potentially block the caller thread. Instead of blocking, the custom deleter may move
- the running task into a separate thread and implement the blocking destruction there.
- In this way, the fast destruction (seen from the caller thread) of the running task
- with a blocking destructor may be achieved.
-
- For more information on implementing the custom task adapters, refer to \l {Task Adapters}.
-
- \sa start(), done(), task()
-*/
-
-/*!
- \fn template <typename Task, typename Deleter = std::default_delete<Task>> TaskAdapter<Task, Deleter>::TaskAdapter<Task, Deleter>()
-
- Creates a task adapter for the given \c Task type.
-
- Internally, it creates an instance of \c Task, which is accessible via the task() method.
- The optionally provided \c Deleter is used instead of the \c Task destructor.
- When \c Deleter is omitted, the \c std::default_delete<Task> is used by default.
-
- \sa task()
-*/
-
-/*!
- \fn template <typename Task, typename Deleter = std::default_delete<Task>> Task *TaskAdapter<Task, Deleter>::task()
-
- Returns the pointer to the associated \c Task instance.
-*/
-
-/*!
- \fn template <typename Task, typename Deleter = std::default_delete<Task>> Task *TaskAdapter<Task, Deleter>::task() const
- \overload
-
- Returns the \c const pointer to the associated \c Task instance.
-*/
-
-/*!
- \class Tasking::Storage
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief A class template for custom data exchange in the running task tree.
- \reentrant
-
- The Storage class template is responsible for dynamically creating and destructing objects
- of the custom \c StorageStruct type. The creation and destruction are managed by the
- running task tree. If a Storage object is placed inside a \l {Tasking::Group} {Group} element,
- the running task tree creates the \c StorageStruct object when the group is started and before
- the group's setup handler is called. Later, whenever any handler inside this group is called,
- the task tree activates the previously created instance of the \c StorageStruct object.
- This includes all tasks' and groups' setup and done handlers inside the group where the
- Storage object was placed, also within the nested groups.
- When a copy of the Storage object is passed to the handler via the lambda capture,
- the handler may access the instance activated by the running task tree via the
- \l {Tasking::Storage::operator->()} {operator->()},
- \l {Tasking::Storage::operator*()} {operator*()}, or activeStorage() method.
- If two handlers capture the same Storage object, one of them may store a custom data there,
- and the other may read it afterwards.
- When the group is finished, the previously created instance of the \c StorageStruct
- object is destroyed after the group's done handler is called.
-
- An example of data exchange between tasks:
-
- \code
- const Storage<QString> storage;
-
- const auto onFirstDone = [storage](const Task &task) {
- // Assings QString, taken from the first task result, to the active QString instance
- // of the Storage object.
- *storage = task.getResultAsString();
- };
-
- const auto onSecondSetup = [storage](Task &task) {
- // Reads QString from the active QString instance of the Storage object and use it to
- // configure the second task before start.
- task.configureWithString(*storage);
- };
-
- const Group root {
- // The running task tree creates QString instance when root in entered
- storage,
- // The done handler of the first task stores the QString in the storage
- TaskItem(..., onFirstDone),
- // The setup handler of the second task reads the QString from the storage
- TaskItem(onSecondSetup, ...)
- };
- \endcode
-
- Since the root group executes its tasks sequentially, the \c onFirstDone handler
- is always called before the \c onSecondSetup handler. This means that the QString data,
- read from the \c storage inside the \c onSecondSetup handler's body,
- has already been set by the \c onFirstDone handler.
- You can always rely on it in \l {Tasking::sequential} {sequential} execution mode.
-
- The Storage internals are shared between all of its copies. That is why the copies of the
- Storage object inside the handlers' lambda captures still refer to the same Storage instance.
- You may place multiple Storage objects inside one \l {Tasking::Group} {Group} element,
- provided that they do not include copies of the same Storage object.
- Otherwise, an assert is triggered at runtime that includes an error message.
- However, you can place copies of the same Storage object in different
- \l {Tasking::Group} {Group} elements of the same recipe. In this case, the running task
- tree will create multiple instances of the \c StorageStruct objects (one for each copy)
- and storage shadowing will take place. Storage shadowing works in a similar way
- to C++ variable shadowing inside the nested blocks of code:
-
- \code
- Storage<QString> storage;
-
- const Group root {
- storage, // Top copy, 1st instance of StorageStruct
- onGroupSetup([storage] { ... }), // Top copy is active
- Group {
- storage, // Nested copy, 2nd instance of StorageStruct,
- // shadows Top copy
- onGroupSetup([storage] { ... }), // Nested copy is active
- },
- Group {
- onGroupSetup([storage] { ... }), // Top copy is active
- }
- };
- \endcode
-
- The Storage objects may also be used for passing the initial data to the executed task tree,
- and for reading the final data out of the task tree before it finishes.
- To do this, use \l {TaskTree::onStorageSetup()} {onStorageSetup()} or
- \l {TaskTree::onStorageDone()} {onStorageDone()}, respectively.
-
- \note If you use an unreachable Storage object inside the handler,
- because you forgot to place the storage in the recipe,
- or placed it, but not in any handler's ancestor group,
- you may expect a crash, preceded by the following message:
- \e {The referenced storage is not reachable in the running tree.
- A nullptr will be returned which might lead to a crash in the calling code.
- It is possible that no storage was added to the tree,
- or the storage is not reachable from where it is referenced.}
-*/
-
-/*!
- \fn template <typename StorageStruct> Storage<StorageStruct>::Storage<StorageStruct>()
-
- Creates a storage for the given \c StorageStruct type.
-
- \note All copies of \c this object are considered to be the same Storage instance.
-*/
-
-/*!
- \fn template <typename StorageStruct> StorageStruct &Storage<StorageStruct>::operator*() const noexcept
-
- Returns a \e reference to the active \c StorageStruct object, created by the running task tree.
- Use this function only from inside the handler body of any GroupItem element placed
- in the recipe, otherwise you may expect a crash.
- Make sure that Storage is placed in any group ancestor of the handler's group item.
-
- \note The returned reference is valid as long as the group that created this instance
- is still running.
-
- \sa activeStorage(), operator->()
-*/
-
-/*!
- \fn template <typename StorageStruct> StorageStruct *Storage<StorageStruct>::operator->() const noexcept
-
- Returns a \e pointer to the active \c StorageStruct object, created by the running task tree.
- Use this function only from inside the handler body of any GroupItem element placed
- in the recipe, otherwise you may expect a crash.
- Make sure that Storage is placed in any group ancestor of the handler's group item.
-
- \note The returned pointer is valid as long as the group that created this instance
- is still running.
-
- \sa activeStorage(), operator*()
-*/
-
-/*!
- \fn template <typename StorageStruct> StorageStruct *Storage<StorageStruct>::activeStorage() const
-
- Returns a \e pointer to the active \c StorageStruct object, created by the running task tree.
- Use this function only from inside the handler body of any GroupItem element placed
- in the recipe, otherwise you may expect a crash.
- Make sure that Storage is placed in any group ancestor of the handler's group item.
-
- \note The returned pointer is valid as long as the group that created this instance
- is still running.
-
- \sa operator->(), operator*()
-*/
-
-/*!
- \typealias Tasking::GroupItems
-
- Type alias for QList<GroupItem>.
-*/
-
-/*!
- \class Tasking::GroupItem
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief GroupItem represents the basic element that may be a part of any Group.
- \reentrant
-
- GroupItem is a basic element that may be a part of any \l {Tasking::Group} {Group}.
- It encapsulates the functionality provided by any GroupItem's subclass.
- It is a value type and it is safe to copy the GroupItem instance,
- even when it is originally created via the subclass' constructor.
-
- There are four main kinds of GroupItem:
- \table
- \header
- \li GroupItem Kind
- \li Brief Description
- \row
- \li \l CustomTask
- \li Defines asynchronous task type and task's start, done, and error handlers.
- Aliased with a unique task name, such as, \c ConcurrentCallTask<ResultType>
- or \c NetworkQueryTask. Asynchronous tasks are the main reason for using a task tree.
- \row
- \li \l {Tasking::Group} {Group}
- \li A container for other group items. Since the group is of the GroupItem type,
- it's possible to nest it inside another group. The group is seen by its parent
- as a single asynchronous task.
- \row
- \li GroupItem containing \l {Tasking::Storage} {Storage}
- \li Enables the child tasks of a group to exchange data. When GroupItem containing
- \l {Tasking::Storage} {Storage} is placed inside a group, the task tree instantiates
- the storage's data object just before the group is entered,
- and destroys it just after the group is left.
- \row
- \li Other group control items
- \li The items returned by \l {Tasking::parallelLimit()} {parallelLimit()} or
- \l {Tasking::workflowPolicy()} {workflowPolicy()} influence the group's behavior.
- The items returned by \l {Tasking::onGroupSetup()} {onGroupSetup()} or
- \l {Tasking::onGroupDone()} {onGroupDone()} define custom handlers called when
- the group starts or ends execution.
- \endtable
-*/
-
-/*!
- \fn template <typename StorageStruct> GroupItem::GroupItem(const Storage<StorageStruct> &storage)
-
- Constructs a \c GroupItem element holding the \a storage object.
-
- When the \l {Tasking::Group} {Group} element containing \e this GroupItem is entered
- by the running task tree, an instance of the \c StorageStruct is created dynamically.
-
- When that group is about to be left after its execution, the previously instantiated
- \c StorageStruct is deleted.
-
- The dynamically created instance of \c StorageStruct is accessible from inside any
- handler body of the parent \l {Tasking::Group} {Group} element,
- including nested groups and its tasks, via the
- \l {Tasking::Storage::operator->()} {Storage::operator->()},
- \l {Tasking::Storage::operator*()} {Storage::operator*()}, or Storage::activeStorage() method.
-
- \sa {Tasking::Storage} {Storage}
-*/
-
-/*!
- \fn GroupItem::GroupItem(const GroupItems &items)
-
- Constructs a \c GroupItem element with a given list of \a items.
-
- When this \c GroupItem element is parsed by the TaskTree, it is simply replaced with
- its \a items.
-
- This constructor is useful when constructing a \l {Tasking::Group} {Group} element with
- lists of \c GroupItem elements:
-
- \code
- static QList<GroupItems> getItems();
-
- ...
-
- const Group root {
- parallel,
- finishAllAndSuccess,
- getItems(), // OK, getItems() list is wrapped into a single GroupItem element
- onGroupSetup(...),
- onGroupDone(...)
- };
- \endcode
-
- If you want to create a subtree, use \l {Tasking::Group} {Group} instead.
-
- \note Don't confuse this \c GroupItem with the \l {Tasking::Group} {Group} element, as
- \l {Tasking::Group} {Group} keeps its children nested
- after being parsed by the task tree, while this \c GroupItem does not.
-
- \sa {Tasking::Group} {Group}
-*/
-
-/*!
- \fn Tasking::GroupItem(std::initializer_list<GroupItem> items)
- \overload
- \sa GroupItem(const GroupItems &items)
-*/
-
-/*!
- \class Tasking::Group
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief Group represents the basic element for composing declarative recipes describing
- how to execute and handle a nested tree of asynchronous tasks.
- \reentrant
-
- Group is a container for other group items. It encloses child tasks into one unit,
- which is seen by the group's parent as a single, asynchronous task.
- Since Group is of the GroupItem type, it may also be a child of Group.
-
- Insert child tasks into the group by using aliased custom task names, such as,
- \c ConcurrentCallTask<ResultType> or \c NetworkQueryTask:
-
- \code
- const Group group {
- NetworkQueryTask(...),
- ConcurrentCallTask<int>(...)
- };
- \endcode
-
- The group's behavior may be customized by inserting the items returned by
- \l {Tasking::parallelLimit()} {parallelLimit()} or
- \l {Tasking::workflowPolicy()} {workflowPolicy()} functions:
-
- \code
- const Group group {
- parallel,
- continueOnError,
- NetworkQueryTask(...),
- NetworkQueryTask(...)
- };
- \endcode
-
- The group may contain nested groups:
-
- \code
- const Group group {
- finishAllAndSuccess,
- NetworkQueryTask(...),
- Group {
- NetworkQueryTask(...),
- Group {
- parallel,
- NetworkQueryTask(...),
- NetworkQueryTask(...),
- }
- ConcurrentCallTask<QString>(...)
- }
- };
- \endcode
-
- The group may dynamically instantiate a custom storage structure, which may be used for
- inter-task data exchange:
-
- \code
- struct MyCustomStruct { QByteArray data; };
-
- Storage<MyCustomStruct> storage;
-
- const auto onFirstSetup = [](NetworkQuery &task) { ... };
- const auto onFirstDone = [storage](const NetworkQuery &task) {
- // storage-> gives a pointer to MyCustomStruct instance,
- // created dynamically by the running task tree.
- storage->data = task.reply()->readAll();
- };
- const auto onSecondSetup = [storage](ConcurrentCall<QImage> &task) {
- // storage-> gives a pointer to MyCustomStruct. Since the group is sequential,
- // the stored MyCustomStruct was already updated inside the onFirstDone handler.
- const QByteArray storedData = storage->data;
- };
-
- const Group group {
- // When the group is entered by a running task tree, it creates MyCustomStruct
- // instance dynamically. It is later accessible from all handlers via
- // the *storage or storage-> operators.
- sequential,
- storage,
- NetworkQueryTask(onFirstSetup, onFirstDone, CallDoneIf::Success),
- ConcurrentCallTask<QImage>(onSecondSetup)
- };
- \endcode
-*/
-
-/*!
- \fn Group::Group(const GroupItems &children)
-
- Constructs a group with a given list of \a children.
-
- This constructor is useful when the child items of the group are not known at compile time,
- but later, at runtime:
-
- \code
- const QStringList sourceList = ...;
-
- GroupItems groupItems { parallel };
-
- for (const QString &source : sourceList) {
- const NetworkQueryTask task(...); // use source for setup handler
- groupItems << task;
- }
-
- const Group group(groupItems);
- \endcode
-*/
-
-/*!
- \fn Group::Group(std::initializer_list<GroupItem> children)
-
- Constructs a group from \c std::initializer_list given by \a children.
-
- This constructor is useful when all child items of the group are known at compile time:
-
- \code
- const Group group {
- finishAllAndSuccess,
- NetworkQueryTask(...),
- Group {
- NetworkQueryTask(...),
- Group {
- parallel,
- NetworkQueryTask(...),
- NetworkQueryTask(...),
- }
- ConcurrentCallTask<QString>(...)
- }
- };
- \endcode
-*/
-
-/*!
- \class Tasking::Sync
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief Synchronously executes a custom handler between other tasks.
- \reentrant
-
- \c Sync is useful when you want to execute an additional handler between other tasks.
- \c Sync is seen by its parent \l {Tasking::Group} {Group} as any other task.
- Avoid long-running execution of the \c Sync's handler body, since it is executed
- synchronously from the caller thread. If that is unavoidable, consider using
- \c ConcurrentCallTask instead.
-*/
-
-/*!
- \fn template <typename Handler> Sync::Sync(Handler &&handler)
-
- Constructs an element that executes a passed \a handler synchronously.
- The \c Handler is of the \c std::function<DoneResult()> type.
- The DoneResult value, returned by the \a handler, is considered during parent group's
- \l {workflowPolicy} {workflow policy} resolution.
- Optionally, the shortened form of \c std::function<void()> is also accepted.
- In this case, it's assumed that the return value is DoneResult::Success.
-
- The passed \a handler executes synchronously from the caller thread, so avoid a long-running
- execution of the handler body. Otherwise, consider using \c ConcurrentCallTask.
-
- \note The \c Sync element is not counted as a task when reporting task tree progress,
- and is not included in TaskTree::taskCount() or TaskTree::progressMaximum().
-*/
-
-/*!
- \class Tasking::CustomTask
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief A class template used for declaring custom task items and defining their setup
- and done handlers.
- \reentrant
-
- Describes custom task items within task tree recipes.
-
- Custom task names are aliased with unique names using the \c CustomTask template
- with a given TaskAdapter subclass as a template parameter.
- For example, \c ConcurrentCallTask<T> is an alias to the \c CustomTask that is defined
- to work with \c ConcurrentCall<T> as an associated task class.
- The following table contains example custom tasks and their associated task classes:
-
- \table
- \header
- \li Aliased Task Name (Tasking Namespace)
- \li Associated Task Class
- \li Brief Description
- \row
- \li ConcurrentCallTask<ReturnType>
- \li ConcurrentCall<ReturnType>
- \li Starts an asynchronous task. Runs in a separate thread.
- \row
- \li NetworkQueryTask
- \li NetworkQuery
- \li Sends a network query.
- \row
- \li TaskTreeTask
- \li TaskTree
- \li Starts a nested task tree.
- \row
- \li TimeoutTask
- \li \c std::chrono::milliseconds
- \li Starts a timer.
- \row
- \li WaitForBarrierTask
- \li MultiBarrier<Limit>
- \li Starts an asynchronous task waiting for the barrier to pass.
- \endtable
-*/
-
-/*!
- \typealias Tasking::CustomTask::Task
-
- Type alias for the task type associated with the custom task's \c Adapter.
-*/
-
-/*!
- \typealias Tasking::CustomTask::Deleter
-
- Type alias for the task's type deleter associated with the custom task's \c Adapter.
-*/
-
-/*!
- \typealias Tasking::CustomTask::TaskSetupHandler
-
- Type alias for \c std::function<SetupResult(Task &)>.
-
- The \c TaskSetupHandler is an optional argument of a custom task element's constructor.
- Any function with the above signature, when passed as a task setup handler,
- will be called by the running task tree after the task is created and before it is started.
-
- Inside the body of the handler, you may configure the task according to your needs.
- The additional parameters, including storages, may be passed to the handler
- via the lambda capture.
- You can decide dynamically whether the task should be started or skipped with
- success or an error.
-
- \note Do not start the task inside the start handler by yourself. Leave it for TaskTree,
- otherwise the behavior is undefined.
-
- The return value of the handler instructs the running task tree on how to proceed
- after the handler's invocation is finished. The return value of SetupResult::Continue
- instructs the task tree to continue running, that is, to execute the associated \c Task.
- The return value of SetupResult::StopWithSuccess or SetupResult::StopWithError
- instructs the task tree to skip the task's execution and finish it immediately with
- success or an error, respectively.
-
- When the return type is either SetupResult::StopWithSuccess or SetupResult::StopWithError,
- the task's done handler (if provided) isn't called afterwards.
-
- The constructor of a custom task accepts also functions in the shortened form of
- \c std::function<void(Task &)>, that is, the return value is \c void.
- In this case, it's assumed that the return value is SetupResult::Continue.
-
- \sa CustomTask(), TaskDoneHandler, GroupSetupHandler
-*/
-
-/*!
- \typealias Tasking::CustomTask::TaskDoneHandler
-
- Type alias for \c std::function<DoneResult(const Task &, DoneWith)> or DoneResult.
-
- The \c TaskDoneHandler is an optional argument of a custom task element's constructor.
- Any function with the above signature, when passed as a task done handler,
- will be called by the running task tree after the task execution finished and before
- the final result of the execution is reported back to the parent group.
-
- Inside the body of the handler you may retrieve the final data from the finished task.
- The additional parameters, including storages, may be passed to the handler
- via the lambda capture.
- It is also possible to decide dynamically whether the task should finish with its return
- value, or the final result should be tweaked.
-
- The DoneWith argument is optional and your done handler may omit it.
- When provided, it holds the info about the final result of a task that will be
- reported to its parent.
-
- If you do not plan to read any data from the finished task,
- you may omit the \c {const Task &} argument.
-
- The returned DoneResult value is optional and your handler may return \c void instead.
- In this case, the final result of the task will be equal to the value indicated by
- the DoneWith argument. When the handler returns the DoneResult value,
- the task's final result may be tweaked inside the done handler's body by the returned value.
-
- For a \c TaskDoneHandler of the DoneResult type, no additional handling is executed,
- and the task finishes unconditionally with the passed value of DoneResult.
-
- \sa CustomTask(), TaskSetupHandler, GroupDoneHandler
-*/
-
-/*!
- \fn template <typename Adapter> template <typename SetupHandler = TaskSetupHandler, typename DoneHandler = TaskDoneHandler> CustomTask<Adapter>::CustomTask(SetupHandler &&setup = TaskSetupHandler(), DoneHandler &&done = TaskDoneHandler(), CallDoneIf callDoneIf = CallDoneIf::SuccessOrError)
-
- Constructs a \c CustomTask instance and attaches the \a setup and \a done handlers to the task.
- When the running task tree is about to start the task,
- it instantiates the associated \l Task object, invokes \a setup handler with a \e reference
- to the created task, and starts it. When the running task finishes,
- the task tree invokes a \a done handler, with a \c const \e reference to the created task.
-
- The passed \a setup handler is of the \l TaskSetupHandler type. For example:
-
- \code
- static void parseAndLog(const QString &input);
-
- ...
-
- const QString input = ...;
-
- const auto onFirstSetup = [input](ConcurrentCall<void> &task) {
- if (input == "Skip")
- return SetupResult::StopWithSuccess; // This task won't start, the next one will
- if (input == "Error")
- return SetupResult::StopWithError; // This task and the next one won't start
- task.setConcurrentCallData(parseAndLog, input);
- // This task will start, and the next one will start after this one finished with success
- return SetupResult::Continue;
- };
-
- const auto onSecondSetup = [input](ConcurrentCall<void> &task) {
- task.setConcurrentCallData(parseAndLog, input);
- };
-
- const Group group {
- ConcurrentCallTask<void>(onFirstSetup),
- ConcurrentCallTask<void>(onSecondSetup)
- };
- \endcode
-
- The \a done handler is of the \l TaskDoneHandler type.
- By default, the \a done handler is invoked whenever the task finishes.
- Pass a non-default value for the \a callDoneIf argument when you want the handler to be called
- only on a successful or failed execution.
-
- \sa TaskSetupHandler, TaskDoneHandler
-*/
-
-/*!
- \enum Tasking::WorkflowPolicy
-
- This enum describes the possible behavior of the Group element when any group's child task
- finishes its execution. It's also used when the running Group is canceled.
-
- \value StopOnError
- Default. Corresponds to the stopOnError global element.
- If any child task finishes with an error, the group stops and finishes with an error.
- If all child tasks finished with success, the group finishes with success.
- If a group is empty, it finishes with success.
- \value ContinueOnError
- Corresponds to the continueOnError global element.
- Similar to stopOnError, but in case any child finishes with an error,
- the execution continues until all tasks finish, and the group reports an error
- afterwards, even when some other tasks in the group finished with success.
- If all child tasks finish successfully, the group finishes with success.
- If a group is empty, it finishes with success.
- \value StopOnSuccess
- Corresponds to the stopOnSuccess global element.
- If any child task finishes with success, the group stops and finishes with success.
- If all child tasks finished with an error, the group finishes with an error.
- If a group is empty, it finishes with an error.
- \value ContinueOnSuccess
- Corresponds to the continueOnSuccess global element.
- Similar to stopOnSuccess, but in case any child finishes successfully,
- the execution continues until all tasks finish, and the group reports success
- afterwards, even when some other tasks in the group finished with an error.
- If all child tasks finish with an error, the group finishes with an error.
- If a group is empty, it finishes with an error.
- \value StopOnSuccessOrError
- Corresponds to the stopOnSuccessOrError global element.
- The group starts as many tasks as it can. When any task finishes,
- the group stops and reports the task's result.
- Useful only in parallel mode.
- In sequential mode, only the first task is started, and when finished,
- the group finishes too, so the other tasks are always skipped.
- If a group is empty, it finishes with an error.
- \value FinishAllAndSuccess
- Corresponds to the finishAllAndSuccess global element.
- The group executes all tasks and ignores their return results. When all
- tasks finished, the group finishes with success.
- If a group is empty, it finishes with success.
- \value FinishAllAndError
- Corresponds to the finishAllAndError global element.
- The group executes all tasks and ignores their return results. When all
- tasks finished, the group finishes with an error.
- If a group is empty, it finishes with an error.
-
- Whenever a child task's result causes the Group to stop, that is,
- in case of StopOnError, StopOnSuccess, or StopOnSuccessOrError policies,
- the Group cancels the other running child tasks (if any - for example in parallel mode),
- and skips executing tasks it has not started yet (for example, in the sequential mode -
- those, that are placed after the failed task). Both canceling and skipping child tasks
- may happen when parallelLimit() is used.
-
- The table below summarizes the differences between various workflow policies:
-
- \table
- \header
- \li \l WorkflowPolicy
- \li Executes all child tasks
- \li Result
- \li Result when the group is empty
- \row
- \li StopOnError
- \li Stops when any child task finished with an error and reports an error
- \li An error when at least one child task failed, success otherwise
- \li Success
- \row
- \li ContinueOnError
- \li Yes
- \li An error when at least one child task failed, success otherwise
- \li Success
- \row
- \li StopOnSuccess
- \li Stops when any child task finished with success and reports success
- \li Success when at least one child task succeeded, an error otherwise
- \li An error
- \row
- \li ContinueOnSuccess
- \li Yes
- \li Success when at least one child task succeeded, an error otherwise
- \li An error
- \row
- \li StopOnSuccessOrError
- \li Stops when any child task finished and reports child task's result
- \li Success or an error, depending on the finished child task's result
- \li An error
- \row
- \li FinishAllAndSuccess
- \li Yes
- \li Success
- \li Success
- \row
- \li FinishAllAndError
- \li Yes
- \li An error
- \li An error
- \endtable
-
- If a child of a group is also a group, the child group runs its tasks according to its own
- workflow policy. When a parent group stops the running child group because
- of parent group's workflow policy, that is, when the StopOnError, StopOnSuccess,
- or StopOnSuccessOrError policy was used for the parent,
- the child group's result is reported according to the
- \b Result column and to the \b {child group's workflow policy} row in the table above.
-*/
-
-/*!
- \variable Tasking::nullItem
-
- A convenient global group's element indicating a no-op item.
-
- This is useful in conditional expressions to indicate the absence of an optional element:
-
- \code
- const ExecutableItem task = ...;
- const std::optional<ExecutableItem> optionalTask = ...;
-
- Group group {
- task,
- optionalTask ? *optionalTask : nullItem
- };
- \endcode
-*/
-
-/*!
- \variable Tasking::successItem
-
- A convenient global executable element containing an empty, successful, synchronous task.
-
- This is useful in if-statements to indicate that a branch ends with success:
-
- \code
- const ExecutableItem conditionalTask = ...;
-
- Group group {
- stopOnDone,
- If (conditionalTask) >> Then {
- ...
- } >> Else {
- successItem
- },
- nextTask
- };
- \endcode
-
- In the above example, if the \c conditionalTask finishes with an error, the \c Else branch
- is chosen, which finishes immediately with success. This causes the \c nextTask to be skipped
- (because of the stopOnDone workflow policy of the \c group)
- and the \c group finishes with success.
-
- \sa errorItem
-*/
-
-/*!
- \variable Tasking::errorItem
-
- A convenient global executable element containing an empty, erroneous, synchronous task.
-
- This is useful in if-statements to indicate that a branch ends with an error:
-
- \code
- const ExecutableItem conditionalTask = ...;
-
- Group group {
- stopOnError,
- If (conditionalTask) >> Then {
- ...
- } >> Else {
- errorItem
- },
- nextTask
- };
- \endcode
-
- In the above example, if the \c conditionalTask finishes with an error, the \c Else branch
- is chosen, which finishes immediately with an error. This causes the \c nextTask to be skipped
- (because of the stopOnError workflow policy of the \c group)
- and the \c group finishes with an error.
-
- \sa successItem
-*/
-
-/*!
- \variable Tasking::sequential
- A convenient global group's element describing the sequential execution mode.
-
- This is the default execution mode of the Group element.
-
- When a Group has no execution mode, it runs in the sequential mode.
- All the direct child tasks of a group are started in a chain, so that when one task finishes,
- the next one starts. This enables you to pass the results from the previous task
- as input to the next task before it starts. This mode guarantees that the next task
- is started only after the previous task finishes.
-
- \sa parallel, parallelLimit()
-*/
-
-/*!
- \variable Tasking::parallel
- A convenient global group's element describing the parallel execution mode.
-
- All the direct child tasks of a group are started after the group is started,
- without waiting for the previous child tasks to finish.
- In this mode, all child tasks run simultaneously.
-
- \sa sequential, parallelLimit()
-*/
-
-/*!
- \variable Tasking::parallelIdealThreadCountLimit
- A convenient global group's element describing the parallel execution mode with a limited
- number of tasks running simultanously. The limit is equal to the ideal number of threads
- excluding the calling thread.
-
- This is a shortcut to:
- \code
- parallelLimit(qMax(QThread::idealThreadCount() - 1, 1))
- \endcode
-
- \sa parallel, parallelLimit()
-*/
-
-/*!
- \variable Tasking::stopOnError
- A convenient global group's element describing the StopOnError workflow policy.
-
- This is the default workflow policy of the Group element.
-*/
-
-/*!
- \variable Tasking::continueOnError
- A convenient global group's element describing the ContinueOnError workflow policy.
-*/
-
-/*!
- \variable Tasking::stopOnSuccess
- A convenient global group's element describing the StopOnSuccess workflow policy.
-*/
-
-/*!
- \variable Tasking::continueOnSuccess
- A convenient global group's element describing the ContinueOnSuccess workflow policy.
-*/
-
-/*!
- \variable Tasking::stopOnSuccessOrError
- A convenient global group's element describing the StopOnSuccessOrError workflow policy.
-*/
-
-/*!
- \variable Tasking::finishAllAndSuccess
- A convenient global group's element describing the FinishAllAndSuccess workflow policy.
-*/
-
-/*!
- \variable Tasking::finishAllAndError
- A convenient global group's element describing the FinishAllAndError workflow policy.
-*/
-
-/*!
- \enum Tasking::SetupResult
-
- This enum is optionally returned from the group's or task's setup handler function.
- It instructs the running task tree on how to proceed after the setup handler's execution
- finished.
- \value Continue
- Default. The group's or task's execution continues normally.
- When a group's or task's setup handler returns void, it's assumed that
- it returned Continue.
- \value StopWithSuccess
- The group's or task's execution stops immediately with success.
- When returned from the group's setup handler, all child tasks are skipped,
- and the group's onGroupDone() handler is invoked with DoneWith::Success.
- The group reports success to its parent. The group's workflow policy is ignored.
- When returned from the task's setup handler, the task isn't started,
- its done handler isn't invoked, and the task reports success to its parent.
- \value StopWithError
- The group's or task's execution stops immediately with an error.
- When returned from the group's setup handler, all child tasks are skipped,
- and the group's onGroupDone() handler is invoked with DoneWith::Error.
- The group reports an error to its parent. The group's workflow policy is ignored.
- When returned from the task's setup handler, the task isn't started,
- its error handler isn't invoked, and the task reports an error to its parent.
-*/
-
-/*!
- \enum Tasking::DoneResult
-
- This enum is optionally returned from the group's or task's done handler function.
- When the done handler doesn't return any value, that is, its return type is \c void,
- its final return value is automatically deduced by the running task tree and reported
- to its parent group.
-
- When the done handler returns the DoneResult, you can tweak the final return value
- inside the handler.
-
- When the DoneResult is returned by the group's done handler, the group's workflow policy
- is ignored.
-
- This enum is also used inside the TaskInterface::done() signal and it indicates whether
- the task finished with success or an error.
-
- \value Success
- The group's or task's execution ends with success.
- \value Error
- The group's or task's execution ends with an error.
-*/
-
-/*!
- \enum Tasking::DoneWith
-
- This enum is an optional argument for the group's or task's done handler.
- It indicates whether the group or task finished with success or an error, or it was canceled.
-
- It is also used as an argument inside the TaskTree::done() signal,
- indicating the final result of the TaskTree execution.
-
- \value Success
- The group's or task's execution ended with success.
- \value Error
- The group's or task's execution ended with an error.
- \value Cancel
- The group's or task's execution was canceled. This happens when the user calls
- TaskTree::cancel() for the running task tree or when the group's workflow policy
- results in canceling some of its running children.
- Tweaking the done handler's final result by returning Tasking::DoneResult from
- the handler is no-op when the group's or task's execution was canceled.
-*/
-
-/*!
- \enum Tasking::CallDoneIf
-
- This enum is an optional argument for the \l onGroupDone() element or custom task's constructor.
- It instructs the task tree on when the group's or task's done handler should be invoked.
-
- \value SuccessOrError
- The done handler is always invoked.
- \value Success
- The done handler is invoked only after successful execution,
- that is, when DoneWith::Success.
- \value Error
- The done handler is invoked only after failed execution,
- that is, when DoneWith::Error or when DoneWith::Cancel.
-*/
-
-/*!
- \typealias Tasking::GroupItem::GroupSetupHandler
-
- Type alias for \c std::function<SetupResult()>.
-
- The \c GroupSetupHandler is an argument of the onGroupSetup() element.
- Any function with the above signature, when passed as a group setup handler,
- will be called by the running task tree when the group execution starts.
-
- The return value of the handler instructs the running group on how to proceed
- after the handler's invocation is finished. The default return value of SetupResult::Continue
- instructs the group to continue running, that is, to start executing its child tasks.
- The return value of SetupResult::StopWithSuccess or SetupResult::StopWithError
- instructs the group to skip the child tasks' execution and finish immediately with
- success or an error, respectively.
-
- When the return type is either SetupResult::StopWithSuccess or SetupResult::StopWithError,
- the group's done handler (if provided) is called synchronously immediately afterwards.
-
- \note Even if the group setup handler returns StopWithSuccess or StopWithError,
- the group's done handler is invoked. This behavior differs from that of task done handler
- and might change in the future.
-
- The onGroupSetup() element accepts also functions in the shortened form of
- \c std::function<void()>, that is, the return value is \c void.
- In this case, it's assumed that the return value is SetupResult::Continue.
-
- \sa onGroupSetup(), GroupDoneHandler, CustomTask::TaskSetupHandler
-*/
-
-/*!
- \typealias Tasking::GroupItem::GroupDoneHandler
-
- Type alias for \c std::function<DoneResult(DoneWith)> or DoneResult.
-
- The \c GroupDoneHandler is an argument of the onGroupDone() element.
- Any function with the above signature, when passed as a group done handler,
- will be called by the running task tree when the group execution ends.
-
- The DoneWith argument is optional and your done handler may omit it.
- When provided, it holds the info about the final result of a group that will be
- reported to its parent.
-
- The returned DoneResult value is optional and your handler may return \c void instead.
- In this case, the final result of the group will be equal to the value indicated by
- the DoneWith argument. When the handler returns the DoneResult value,
- the group's final result may be tweaked inside the done handler's body by the returned value.
-
- For a \c GroupDoneHandler of the DoneResult type, no additional handling is executed,
- and the group finishes unconditionally with the passed value of DoneResult,
- ignoring the group's workflow policy.
-
- \sa onGroupDone(), GroupSetupHandler, CustomTask::TaskDoneHandler
-*/
-
-/*!
- \fn template <typename Handler> GroupItem onGroupSetup(Handler &&handler)
-
- Constructs a group's element holding the group setup handler.
- The \a handler is invoked whenever the group starts.
-
- The passed \a handler is either of the \c std::function<SetupResult()> or the
- \c std::function<void()> type. For more information on a possible handler type, refer to
- \l {GroupItem::GroupSetupHandler}.
-
- When the \a handler is invoked, none of the group's child tasks are running yet.
-
- If a group contains the Storage elements, the \a handler is invoked
- after the storages are constructed, so that the \a handler may already
- perform some initial modifications to the active storages.
-
- \sa GroupItem::GroupSetupHandler, onGroupDone()
-*/
-
-/*!
- \fn template <typename Handler> GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError)
-
- Constructs a group's element holding the group done handler.
- By default, the \a handler is invoked whenever the group finishes.
- Pass a non-default value for the \a callDoneIf argument when you want the handler to be called
- only on a successful or failed execution.
- Depending on the group's workflow policy, this handler may also be called
- when the running group is canceled (e.g. when stopOnError element was used).
-
- The passed \a handler is of the \c std::function<DoneResult(DoneWith)> type.
- Optionally, each of the return DoneResult type or the argument DoneWith type may be omitted
- (that is, its return type may be \c void). For more information on a possible handler type,
- refer to \l {GroupItem::GroupDoneHandler}.
-
- When the \a handler is invoked, all of the group's child tasks are already finished.
-
- If a group contains the Storage elements, the \a handler is invoked
- before the storages are destructed, so that the \a handler may still
- perform a last read of the active storages' data.
-
- \sa GroupItem::GroupDoneHandler, onGroupSetup()
-*/
-
-/*!
- Constructs a group's element describing the \l{Execution Mode}{execution mode}.
-
- The execution mode element in a Group specifies how the direct child tasks of
- the Group are started.
-
- For convenience, when appropriate, the \l sequential or \l parallel global elements
- may be used instead.
-
- The \a limit defines the maximum number of direct child tasks running in parallel:
-
- \list
- \li When \a limit equals to 0, there is no limit, and all direct child tasks are started
- together, in the oder in which they appear in a group. This means the fully parallel
- execution, and the \l parallel element may be used instead.
-
- \li When \a limit equals to 1, it means that only one child task may run at the time.
- This means the sequential execution, and the \l sequential element may be used instead.
- In this case, child tasks run in chain, so the next child task starts after
- the previous child task has finished.
-
- \li When other positive number is passed as \a limit, the group's child tasks run
- in parallel, but with a limited number of tasks running simultanously.
- The \e limit defines the maximum number of tasks running in parallel in a group.
- When the group is started, the first batch of tasks is started
- (the number of tasks in a batch equals to the passed \a limit, at most),
- while the others are kept waiting. When any running task finishes,
- the group starts the next remaining one, so that the \e limit of simultaneously
- running tasks inside a group isn't exceeded. This repeats on every child task's
- finish until all child tasks are started. This enables you to limit the maximum
- number of tasks that run simultaneously, for example if running too many processes might
- block the machine for a long time.
- \endlist
-
- In all execution modes, a group starts tasks in the oder in which they appear.
-
- If a child of a group is also a group, the child group runs its tasks according
- to its own execution mode.
-
- \sa sequential, parallel
-*/
-
-GroupItem parallelLimit(int limit)
-{
- struct ParallelLimit : GroupItem {
- ParallelLimit(int limit) : GroupItem({{}, limit}) {}
- };
- return ParallelLimit(limit);
-}
-
-/*!
- Constructs a group's \l {Workflow Policy} {workflow policy} element for a given \a policy.
-
- For convenience, global elements may be used instead.
-
- \sa stopOnError, continueOnError, stopOnSuccess, continueOnSuccess, stopOnSuccessOrError,
- finishAllAndSuccess, finishAllAndError, WorkflowPolicy
-*/
-GroupItem workflowPolicy(WorkflowPolicy policy)
-{
- struct WorkflowPolicyItem : GroupItem {
- WorkflowPolicyItem(WorkflowPolicy policy) : GroupItem({{}, {}, policy}) {}
- };
- return WorkflowPolicyItem(policy);
-}
-
-const GroupItem sequential = parallelLimit(1);
-const GroupItem parallel = parallelLimit(0);
-const GroupItem parallelIdealThreadCountLimit = parallelLimit(qMax(QThread::idealThreadCount() - 1, 1));
-
-const GroupItem stopOnError = workflowPolicy(WorkflowPolicy::StopOnError);
-const GroupItem continueOnError = workflowPolicy(WorkflowPolicy::ContinueOnError);
-const GroupItem stopOnSuccess = workflowPolicy(WorkflowPolicy::StopOnSuccess);
-const GroupItem continueOnSuccess = workflowPolicy(WorkflowPolicy::ContinueOnSuccess);
-const GroupItem stopOnSuccessOrError = workflowPolicy(WorkflowPolicy::StopOnSuccessOrError);
-const GroupItem finishAllAndSuccess = workflowPolicy(WorkflowPolicy::FinishAllAndSuccess);
-const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError);
-
-// Keep below the above in order to avoid static initialization fiasco.
-const GroupItem nullItem = Group {};
-const ExecutableItem successItem = Group { finishAllAndSuccess };
-const ExecutableItem errorItem = Group { finishAllAndError };
-
-Group operator>>(const For &forItem, const Do &doItem)
-{
- return {forItem.m_loop, doItem.m_children};
-}
-
-Group operator>>(const When &whenItem, const Do &doItem)
-{
- const SingleBarrier barrier;
-
- return {
- barrier,
- parallel,
- whenItem.m_barrierKicker(barrier),
- Group {
- waitForBarrierTask(barrier),
- doItem.m_children
- }
- };
-}
-
-// Please note the thread_local keyword below guarantees a separate instance per thread.
-// The s_activeTaskTrees is currently used internally only and is not exposed in the public API.
-// It serves for withLog() implementation now. Add a note here when a new usage is introduced.
-static thread_local QList<TaskTree *> s_activeTaskTrees = {};
-
-static TaskTree *activeTaskTree()
-{
- QT_ASSERT(s_activeTaskTrees.size(), return nullptr);
- return s_activeTaskTrees.back();
-}
-
-DoneResult toDoneResult(bool success)
-{
- return success ? DoneResult::Success : DoneResult::Error;
-}
-
-static SetupResult toSetupResult(bool success)
-{
- return success ? SetupResult::StopWithSuccess : SetupResult::StopWithError;
-}
-
-static DoneResult toDoneResult(DoneWith doneWith)
-{
- return doneWith == DoneWith::Success ? DoneResult::Success : DoneResult::Error;
-}
-
-static DoneWith toDoneWith(DoneResult result)
-{
- return result == DoneResult::Success ? DoneWith::Success : DoneWith::Error;
-}
-
-class LoopThreadData
-{
- Q_DISABLE_COPY_MOVE(LoopThreadData)
-
-public:
- LoopThreadData() = default;
- void pushIteration(int index)
- {
- m_activeLoopStack.push_back(index);
- }
- void popIteration()
- {
- QT_ASSERT(m_activeLoopStack.size(), return);
- m_activeLoopStack.pop_back();
- }
- int iteration() const
- {
- QT_ASSERT(m_activeLoopStack.size(), qWarning(
- "The referenced loop is not reachable in the running tree. "
- "A -1 will be returned which might lead to a crash in the calling code. "
- "It is possible that no loop was added to the tree, "
- "or the loop is not reachable from where it is referenced."); return -1);
- return m_activeLoopStack.last();
- }
-
-private:
- QList<int> m_activeLoopStack;
-};
-
-class LoopData
-{
-public:
- LoopThreadData &threadData() {
- QMutexLocker lock(&m_threadDataMutex);
- return m_threadDataMap.try_emplace(QThread::currentThread()).first->second;
- }
-
- const std::optional<int> m_loopCount = {};
- const Loop::ValueGetter m_valueGetter = {};
- const Loop::Condition m_condition = {};
- QMutex m_threadDataMutex = {};
- // Use std::map on purpose, so that it doesn't invalidate references on modifications.
- // Don't optimize it by using std::unordered_map.
- std::map<QThread *, LoopThreadData> m_threadDataMap = {};
-};
-
-Loop::Loop()
- : m_loopData(new LoopData)
-{}
-
-Loop::Loop(int count, const ValueGetter &valueGetter)
- : m_loopData(new LoopData{count, valueGetter})
-{}
-
-Loop::Loop(const Condition &condition)
- : m_loopData(new LoopData{{}, {}, condition})
-{}
-
-int Loop::iteration() const
-{
- return m_loopData->threadData().iteration();
-}
-
-const void *Loop::valuePtr() const
-{
- return m_loopData->m_valueGetter(iteration());
-}
-
-using StoragePtr = void *;
-
-static constexpr QLatin1StringView s_activeStorageWarning =
- "The referenced storage is not reachable in the running tree. "
- "A nullptr will be returned which might lead to a crash in the calling code. "
- "It is possible that no storage was added to the tree, "
- "or the storage is not reachable from where it is referenced."_L1;
-
-class StorageThreadData
-{
- Q_DISABLE_COPY_MOVE(StorageThreadData)
-
-public:
- StorageThreadData() = default;
- void pushStorage(StoragePtr storagePtr)
- {
- m_activeStorageStack.push_back({storagePtr, activeTaskTree()});
- }
- void popStorage()
- {
- QT_ASSERT(m_activeStorageStack.size(), return);
- m_activeStorageStack.pop_back();
- }
- StoragePtr activeStorage() const
- {
- QT_ASSERT(m_activeStorageStack.size(),
- qWarning().noquote() << s_activeStorageWarning; return nullptr);
- const QPair<StoragePtr, TaskTree *> &top = m_activeStorageStack.last();
- QT_ASSERT(top.second == activeTaskTree(),
- qWarning().noquote() << s_activeStorageWarning; return nullptr);
- return top.first;
- }
-
-private:
- QList<QPair<StoragePtr, TaskTree *>> m_activeStorageStack;
-};
-
-class StorageData
-{
-public:
- StorageThreadData &threadData() {
- QMutexLocker lock(&m_threadDataMutex);
- return m_threadDataMap.try_emplace(QThread::currentThread()).first->second;
- }
-
- const StorageBase::StorageConstructor m_constructor = {};
- const StorageBase::StorageDestructor m_destructor = {};
- QMutex m_threadDataMutex = {};
- // Use std::map on purpose, so that it doesn't invalidate references on modifications.
- // Don't optimize it by using std::unordered_map.
- std::map<QThread *, StorageThreadData> m_threadDataMap = {};
-};
-
-StorageBase::StorageBase(const StorageConstructor &ctor, const StorageDestructor &dtor)
- : m_storageData(new StorageData{ctor, dtor})
-{}
-
-void *StorageBase::activeStorageVoid() const
-{
- return m_storageData->threadData().activeStorage();
-}
-
-void GroupItem::addChildren(const GroupItems &children)
-{
- QT_ASSERT(m_type == Type::Group || m_type == Type::List,
- qWarning("Only Group or List may have children, skipping..."); return);
- if (m_type == Type::List) {
- m_children.append(children);
- return;
- }
- for (const GroupItem &child : children) {
- switch (child.m_type) {
- case Type::List:
- addChildren(child.m_children);
- break;
- case Type::Group:
- m_children.append(child);
- break;
- case Type::GroupData:
- if (child.m_groupData.m_groupHandler.m_setupHandler) {
- QT_ASSERT(!m_groupData.m_groupHandler.m_setupHandler,
- qWarning("Group setup handler redefinition, overriding..."));
- m_groupData.m_groupHandler.m_setupHandler
- = child.m_groupData.m_groupHandler.m_setupHandler;
- }
- if (child.m_groupData.m_groupHandler.m_doneHandler) {
- QT_ASSERT(!m_groupData.m_groupHandler.m_doneHandler,
- qWarning("Group done handler redefinition, overriding..."));
- m_groupData.m_groupHandler.m_doneHandler
- = child.m_groupData.m_groupHandler.m_doneHandler;
- m_groupData.m_groupHandler.m_callDoneIf
- = child.m_groupData.m_groupHandler.m_callDoneIf;
- }
- if (child.m_groupData.m_parallelLimit) {
- QT_ASSERT(!m_groupData.m_parallelLimit,
- qWarning("Group execution mode redefinition, overriding..."));
- m_groupData.m_parallelLimit = child.m_groupData.m_parallelLimit;
- }
- if (child.m_groupData.m_workflowPolicy) {
- QT_ASSERT(!m_groupData.m_workflowPolicy,
- qWarning("Group workflow policy redefinition, overriding..."));
- m_groupData.m_workflowPolicy = child.m_groupData.m_workflowPolicy;
- }
- if (child.m_groupData.m_loop) {
- QT_ASSERT(!m_groupData.m_loop,
- qWarning("Group loop redefinition, overriding..."));
- m_groupData.m_loop = child.m_groupData.m_loop;
- }
- break;
- case Type::TaskHandler:
- QT_ASSERT(child.m_taskHandler.m_createHandler,
- qWarning("Task create handler can't be null, skipping..."); return);
- m_children.append(child);
- break;
- case Type::Storage:
- // Check for duplicates, as can't have the same storage twice on the same level.
- for (const StorageBase &storage : child.m_storageList) {
- if (m_storageList.contains(storage)) {
- QT_ASSERT(false, qWarning("Can't add the same storage into one Group twice, "
- "skipping..."));
- continue;
- }
- m_storageList.append(storage);
- }
- break;
- }
- }
-}
-
-/*!
- \class Tasking::ExecutableItem
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief Base class for executable task items.
- \reentrant
-
- \c ExecutableItem provides an additional interface for items containing executable tasks.
- Use withTimeout() to attach a timeout to a task.
- Use withLog() to include debugging information about the task startup and the execution result.
-*/
-
-/*!
- Attaches \c TimeoutTask to a copy of \c this ExecutableItem, elapsing after \a timeout
- in milliseconds, with an optionally provided timeout \a handler, and returns the coupled item.
-
- When the ExecutableItem finishes before \a timeout passes, the returned item finishes
- immediately with the task's result. Otherwise, \a handler is invoked (if provided),
- the task is canceled, and the returned item finishes with an error.
-*/
-Group ExecutableItem::withTimeout(milliseconds timeout,
- const std::function<void()> &handler) const
-{
- const auto onSetup = [timeout](milliseconds &timeoutData) { timeoutData = timeout; };
- return Group {
- parallel,
- stopOnSuccessOrError,
- Group {
- finishAllAndError,
- handler ? TimeoutTask(onSetup, [handler] { handler(); }, CallDoneIf::Success)
- : TimeoutTask(onSetup)
- },
- *this
- };
-}
-
-static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateWithMs); }
-
-static QString logHeader(const QString &logName)
-{
- return QString::fromLatin1("TASK TREE LOG [%1] \"%2\"").arg(currentTime(), logName);
-};
-
-/*!
- Attaches a custom debug printout to a copy of \c this ExecutableItem,
- issued on task startup and after the task is finished, and returns the coupled item.
-
- The debug printout includes a timestamp of the event (start or finish)
- and \a logName to identify the specific task in the debug log.
-
- The finish printout contains the additional information whether the execution was
- synchronous or asynchronous, its result (the value described by the DoneWith enum),
- and the total execution time in milliseconds.
-*/
-Group ExecutableItem::withLog(const QString &logName) const
-{
- struct LogStorage
- {
- time_point<system_clock, nanoseconds> start;
- int asyncCount = 0;
- };
- const Storage<LogStorage> storage;
- return Group {
- storage,
- onGroupSetup([storage, logName] {
- storage->start = system_clock::now();
- storage->asyncCount = activeTaskTree()->asyncCount();
- qDebug().noquote().nospace() << logHeader(logName) << " started.";
- }),
- *this,
- onGroupDone([storage, logName](DoneWith result) {
- const auto elapsed = duration_cast<milliseconds>(system_clock::now() - storage->start);
- const int asyncCountDiff = activeTaskTree()->asyncCount() - storage->asyncCount;
- QT_CHECK(asyncCountDiff >= 0);
- const QMetaEnum doneWithEnum = QMetaEnum::fromType<DoneWith>();
- const QString syncType = asyncCountDiff ? QString::fromLatin1("asynchronously")
- : QString::fromLatin1("synchronously");
- qDebug().noquote().nospace() << logHeader(logName) << " finished " << syncType
- << " with " << doneWithEnum.valueToKey(int(result))
- << " within " << elapsed.count() << "ms.";
- })
- };
-}
-
-/*!
- \fn Group ExecutableItem::operator!(const ExecutableItem &item)
-
- Returns a Group with the DoneResult of \a item negated.
-
- If \a item reports DoneResult::Success, the returned item reports DoneResult::Error.
- If \a item reports DoneResult::Error, the returned item reports DoneResult::Success.
-
- The returned item is equivalent to:
- \code
- Group {
- item,
- onGroupDone([](DoneWith doneWith) { return toDoneResult(doneWith == DoneWith::Error); })
- }
- \endcode
-
- \sa operator&&(), operator||()
-*/
-Group operator!(const ExecutableItem &item)
-{
- return {
- item,
- onGroupDone([](DoneWith doneWith) { return toDoneResult(doneWith == DoneWith::Error); })
- };
-}
-
-/*!
- \fn Group ExecutableItem::operator&&(const ExecutableItem &first, const ExecutableItem &second)
-
- Returns a Group with \a first and \a second tasks merged with conjunction.
-
- Both \a first and \a second tasks execute in sequence.
- If both tasks report DoneResult::Success, the returned item reports DoneResult::Success.
- Otherwise, the returned item reports DoneResult::Error.
-
- The returned item is
- \l {https://en.wikipedia.org/wiki/Short-circuit_evaluation}{short-circuiting}:
- if the \a first task reports DoneResult::Error, the \a second task is skipped,
- and the returned item reports DoneResult::Error immediately.
-
- The returned item is equivalent to:
- \code
- Group { stopOnError, first, second }
- \endcode
-
- \note Parallel execution of conjunction in a short-circuit manner can be achieved with the
- following code: \c {Group { parallel, stopOnError, first, second }}. In this case:
- if the \e {first finished} task reports DoneResult::Error,
- the \e other task is canceled, and the group reports DoneResult::Error immediately.
-
- \sa operator||(), operator!()
-*/
-Group operator&&(const ExecutableItem &first, const ExecutableItem &second)
-{
- return { stopOnError, first, second };
-}
-
-/*!
- \fn Group ExecutableItem::operator||(const ExecutableItem &first, const ExecutableItem &second)
-
- Returns a Group with \a first and \a second tasks merged with disjunction.
-
- Both \a first and \a second tasks execute in sequence.
- If both tasks report DoneResult::Error, the returned item reports DoneResult::Error.
- Otherwise, the returned item reports DoneResult::Success.
-
- The returned item is
- \l {https://en.wikipedia.org/wiki/Short-circuit_evaluation}{short-circuiting}:
- if the \a first task reports DoneResult::Success, the \a second task is skipped,
- and the returned item reports DoneResult::Success immediately.
-
- The returned item is equivalent to:
- \code
- Group { stopOnSuccess, first, second }
- \endcode
-
- \note Parallel execution of disjunction in a short-circuit manner can be achieved with the
- following code: \c {Group { parallel, stopOnSuccess, first, second }}. In this case:
- if the \e {first finished} task reports DoneResult::Success,
- the \e other task is canceled, and the group reports DoneResult::Success immediately.
-
- \sa operator&&(), operator!()
-*/
-Group operator||(const ExecutableItem &first, const ExecutableItem &second)
-{
- return { stopOnSuccess, first, second };
-}
-
-/*!
- \fn Group ExecutableItem::operator&&(const ExecutableItem &item, DoneResult result)
- \overload ExecutableItem::operator&&()
-
- Returns the \a item task if the \a result is DoneResult::Success; otherwise returns
- the \a item task with its done result tweaked to DoneResult::Error.
-
- The \c {task && DoneResult::Error} is an eqivalent to tweaking the task's done result
- into DoneResult::Error unconditionally.
-*/
-Group operator&&(const ExecutableItem &item, DoneResult result)
-{
- return { result == DoneResult::Success ? stopOnError : finishAllAndError, item };
-}
-
-/*!
- \fn Group ExecutableItem::operator||(const ExecutableItem &item, DoneResult result)
- \overload ExecutableItem::operator||()
-
- Returns the \a item task if the \a result is DoneResult::Error; otherwise returns
- the \a item task with its done result tweaked to DoneResult::Success.
-
- The \c {task || DoneResult::Success} is an eqivalent to tweaking the task's done result
- into DoneResult::Success unconditionally.
-*/
-Group operator||(const ExecutableItem &item, DoneResult result)
-{
- return { result == DoneResult::Error ? stopOnError : finishAllAndSuccess, item };
-}
-
-Group ExecutableItem::withCancelImpl(
- const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper,
- const GroupItems &postCancelRecipe) const
-{
- const Storage<bool> canceledStorage(false);
-
- const auto onSetup = [connectWrapper, canceledStorage](Barrier &barrier) {
- connectWrapper(&barrier, [barrierPtr = &barrier, canceled = canceledStorage.activeStorage()] {
- *canceled = true;
- barrierPtr->advance();
- });
- };
-
- const auto wasCanceled = [canceledStorage] { return *canceledStorage; };
-
- return {
- continueOnError,
- canceledStorage,
- Group {
- parallel,
- stopOnSuccessOrError,
- BarrierTask(onSetup) && errorItem,
- *this
- },
- If (wasCanceled) >> Then {
- postCancelRecipe
- }
- };
-}
-
-Group ExecutableItem::withAcceptImpl(
- const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper) const
-{
- const auto onSetup = [connectWrapper](Barrier &barrier) {
- connectWrapper(&barrier, [barrierPtr = &barrier] { barrierPtr->advance(); });
- };
- return Group {
- parallel,
- BarrierTask(onSetup),
- *this
- };
-}
-
-class TaskTreePrivate;
-class TaskNode;
-class RuntimeContainer;
-class RuntimeIteration;
-class RuntimeTask;
-
-class ExecutionContextActivator
-{
-public:
- ExecutionContextActivator(RuntimeIteration *iteration) {
- activateTaskTree(iteration);
- activateContext(iteration);
- }
- ExecutionContextActivator(RuntimeContainer *container) {
- activateTaskTree(container);
- activateContext(container);
- }
- ~ExecutionContextActivator() {
- for (int i = m_activeStorages.size() - 1; i >= 0; --i) // iterate in reverse order
- m_activeStorages[i].m_storageData->threadData().popStorage();
- for (int i = m_activeLoops.size() - 1; i >= 0; --i) // iterate in reverse order
- m_activeLoops[i].m_loopData->threadData().popIteration();
- QT_ASSERT(s_activeTaskTrees.size(), return);
- s_activeTaskTrees.pop_back();
- }
-
-private:
- void activateTaskTree(RuntimeIteration *iteration);
- void activateTaskTree(RuntimeContainer *container);
- void activateContext(RuntimeIteration *iteration);
- void activateContext(RuntimeContainer *container);
- QList<Loop> m_activeLoops;
- QList<StorageBase> m_activeStorages;
-};
-
-class ContainerNode
-{
- Q_DISABLE_COPY(ContainerNode)
-
-public:
- ContainerNode(ContainerNode &&other) = default;
- ContainerNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task);
-
- TaskTreePrivate *const m_taskTreePrivate = nullptr;
-
- const GroupItem::GroupHandler m_groupHandler;
- const int m_parallelLimit = 1;
- const WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError;
- const std::optional<Loop> m_loop;
- const QList<StorageBase> m_storageList;
- std::vector<TaskNode> m_children;
- const int m_taskCount = 0;
-};
-
-class TaskNode
-{
- Q_DISABLE_COPY(TaskNode)
-
-public:
- TaskNode(TaskNode &&other) = default;
- TaskNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task)
- : m_taskHandler(task.m_taskHandler)
- , m_container(taskTreePrivate, task)
- {}
-
- bool isTask() const { return bool(m_taskHandler.m_createHandler); }
- int taskCount() const { return isTask() ? 1 : m_container.m_taskCount; }
-
- const GroupItem::TaskHandler m_taskHandler;
- ContainerNode m_container;
-};
-
-class TaskTreePrivate
-{
- Q_DISABLE_COPY_MOVE(TaskTreePrivate)
-
-public:
- explicit TaskTreePrivate(TaskTree *taskTree);
- ~TaskTreePrivate();
-
- void start();
- void stop();
- void bumpAsyncCount();
- void advanceProgress(int byValue);
- void emitDone(DoneWith result);
- void callSetupHandler(const StorageBase &storage, StoragePtr storagePtr) {
- callStorageHandler(storage, storagePtr, &StorageHandler::m_setupHandler);
- }
- void callDoneHandler(const StorageBase &storage, StoragePtr storagePtr) {
- callStorageHandler(storage, storagePtr, &StorageHandler::m_doneHandler);
- }
- struct StorageHandler {
- StorageBase::StorageHandler m_setupHandler = {};
- StorageBase::StorageHandler m_doneHandler = {};
- };
- typedef StorageBase::StorageHandler StorageHandler::*HandlerPtr; // ptr to class member
- void callStorageHandler(const StorageBase &storage, StoragePtr storagePtr, HandlerPtr ptr)
- {
- const auto it = m_storageHandlers.constFind(storage);
- if (it == m_storageHandlers.constEnd())
- return;
- const StorageHandler storageHandler = *it;
- if (storageHandler.*ptr) {
- GuardLocker locker(m_guard);
- (storageHandler.*ptr)(storagePtr);
- }
- }
-
- // Node related methods
-
- // If returned value != Continue, childDone() needs to be called in parent container (in caller)
- // in order to unwind properly.
- void startTask(const std::shared_ptr<RuntimeTask> &node);
- void stopTask(RuntimeTask *node);
- bool invokeTaskDoneHandler(RuntimeTask *node, DoneWith doneWith);
-
- // Container related methods
-
- void continueContainer(RuntimeContainer *container);
- void startChildren(RuntimeContainer *container);
- void childDone(RuntimeIteration *iteration, bool success);
- void stopContainer(RuntimeContainer *container);
- bool invokeDoneHandler(RuntimeContainer *container, DoneWith doneWith);
- bool invokeLoopHandler(RuntimeContainer *container);
-
- template <typename Container, typename Handler, typename ...Args,
- typename ReturnType = std::invoke_result_t<Handler, Args...>>
- ReturnType invokeHandler(Container *container, Handler &&handler, Args &&...args)
- {
- QT_ASSERT(!m_guard.isLocked(), qWarning("Nested execution of handlers detected."
- "This may happen when one task's handler has entered a nested event loop,"
- "and other task finished during nested event loop's processing, "
- "causing stopping (canceling) the task executing the nested event loop. "
- "This includes the case when QCoreApplication::processEvents() was called from "
- "the handler. It may also happen when the Barrier task is advanced directly "
- "from some other task handler. This will lead to a crash. "
- "Avoid event processing during handlers' execution. "
- "If it can't be avoided, make sure no other tasks are run in parallel when "
- "processing events from the handler."));
- ExecutionContextActivator activator(container);
- GuardLocker locker(m_guard);
- return std::invoke(std::forward<Handler>(handler), std::forward<Args>(args)...);
- }
-
- static int effectiveLoopCount(const std::optional<Loop> &loop)
- {
- return loop && loop->m_loopData->m_loopCount ? *loop->m_loopData->m_loopCount : 1;
- }
-
- TaskTree *q = nullptr;
- Guard m_guard;
- int m_progressValue = 0;
- int m_asyncCount = 0;
- QSet<StorageBase> m_storages;
- QHash<StorageBase, StorageHandler> m_storageHandlers;
- std::optional<TaskNode> m_root;
- std::shared_ptr<RuntimeTask> m_runtimeRoot; // Keep me last in order to destruct first
-};
-
-static bool initialSuccessBit(WorkflowPolicy workflowPolicy)
-{
- switch (workflowPolicy) {
- case WorkflowPolicy::StopOnError:
- case WorkflowPolicy::ContinueOnError:
- case WorkflowPolicy::FinishAllAndSuccess:
- return true;
- case WorkflowPolicy::StopOnSuccess:
- case WorkflowPolicy::ContinueOnSuccess:
- case WorkflowPolicy::StopOnSuccessOrError:
- case WorkflowPolicy::FinishAllAndError:
- return false;
- }
- QT_CHECK(false);
- return false;
-}
-
-static bool isProgressive(RuntimeContainer *container);
-
-class RuntimeIteration
-{
- Q_DISABLE_COPY(RuntimeIteration)
-
-public:
- RuntimeIteration(int index, RuntimeContainer *container);
- ~RuntimeIteration();
- std::optional<Loop> loop() const;
- void removeChild(RuntimeTask *node);
-
- const int m_iterationIndex = 0;
- const bool m_isProgressive = true;
- RuntimeContainer *m_container = nullptr;
- int m_doneCount = 0;
- std::vector<std::shared_ptr<RuntimeTask>> m_children = {}; // Owning.
-};
-
-class RuntimeContainer
-{
- Q_DISABLE_COPY(RuntimeContainer)
-
-public:
- RuntimeContainer(const ContainerNode &taskContainer, RuntimeTask *parentTask)
- : m_containerNode(taskContainer)
- , m_parentTask(parentTask)
- , m_storages(createStorages(taskContainer))
- , m_successBit(initialSuccessBit(taskContainer.m_workflowPolicy))
- , m_shouldIterate(taskContainer.m_loop)
- {}
-
- ~RuntimeContainer()
- {
- for (int i = m_containerNode.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order
- const StorageBase storage = m_containerNode.m_storageList[i];
- StoragePtr storagePtr = m_storages.value(i);
- if (m_callStorageDoneHandlersOnDestruction)
- m_containerNode.m_taskTreePrivate->callDoneHandler(storage, storagePtr);
- storage.m_storageData->m_destructor(storagePtr);
- }
- }
-
- static QList<StoragePtr> createStorages(const ContainerNode &container);
- bool isStarting() const { return m_startGuard.isLocked(); }
- RuntimeIteration *parentIteration() const;
- bool updateSuccessBit(bool success);
- void deleteFinishedIterations();
- int progressiveLoopCount() const
- {
- return m_containerNode.m_taskTreePrivate->effectiveLoopCount(m_containerNode.m_loop);
- }
-
- const ContainerNode &m_containerNode; // Not owning.
- RuntimeTask *m_parentTask = nullptr; // Not owning.
- const QList<StoragePtr> m_storages; // Owning.
-
- bool m_successBit = true;
- bool m_callStorageDoneHandlersOnDestruction = false;
- Guard m_startGuard;
-
- int m_iterationCount = 0;
- int m_nextToStart = 0;
- int m_runningChildren = 0;
- bool m_shouldIterate = true;
- std::vector<std::unique_ptr<RuntimeIteration>> m_iterations; // Owning.
-};
-
-class RuntimeTask
-{
-public:
- ~RuntimeTask()
- {
- if (m_task) {
- // Ensures the running task's d'tor doesn't emit done() signal. QTCREATORBUG-30204.
- QObject::disconnect(m_task.get(), &TaskInterface::done, nullptr, nullptr);
- }
- }
-
- const TaskNode &m_taskNode; // Not owning.
- RuntimeIteration *m_parentIteration = nullptr; // Not owning.
- std::optional<RuntimeContainer> m_container = {}; // Owning.
- std::unique_ptr<TaskInterface> m_task = {}; // Owning.
- SetupResult m_setupResult = SetupResult::Continue;
-};
-
-RuntimeIteration::~RuntimeIteration() = default;
-
-TaskTreePrivate::TaskTreePrivate(TaskTree *taskTree)
- : q(taskTree) {}
-
-TaskTreePrivate::~TaskTreePrivate() = default;
-
-static bool isProgressive(RuntimeContainer *container)
-{
- RuntimeIteration *iteration = container->m_parentTask->m_parentIteration;
- return iteration ? iteration->m_isProgressive : true;
-}
-
-void ExecutionContextActivator::activateTaskTree(RuntimeIteration *iteration)
-{
- activateTaskTree(iteration->m_container);
-}
-
-void ExecutionContextActivator::activateTaskTree(RuntimeContainer *container)
-{
- s_activeTaskTrees.push_back(container->m_containerNode.m_taskTreePrivate->q);
-}
-
-void ExecutionContextActivator::activateContext(RuntimeIteration *iteration)
-{
- std::optional<Loop> loop = iteration->loop();
- if (loop) {
- loop->m_loopData->threadData().pushIteration(iteration->m_iterationIndex);
- m_activeLoops.append(*loop);
- }
- activateContext(iteration->m_container);
-}
-
-void ExecutionContextActivator::activateContext(RuntimeContainer *container)
-{
- const ContainerNode &containerNode = container->m_containerNode;
- for (int i = 0; i < containerNode.m_storageList.size(); ++i) {
- const StorageBase &storage = containerNode.m_storageList[i];
- if (m_activeStorages.contains(storage))
- continue; // Storage shadowing: The storage is already active, skipping it...
- m_activeStorages.append(storage);
- storage.m_storageData->threadData().pushStorage(container->m_storages.value(i));
- }
- // Go to the parent after activating this storages so that storage shadowing works
- // in the direction from child to parent root.
- if (container->parentIteration())
- activateContext(container->parentIteration());
-}
-
-void TaskTreePrivate::start()
-{
- QT_ASSERT(m_root, return);
- QT_ASSERT(!m_runtimeRoot, return);
- m_asyncCount = 0;
- m_progressValue = 0;
- {
- GuardLocker locker(m_guard);
- emit q->started();
- emit q->asyncCountChanged(m_asyncCount);
- emit q->progressValueChanged(m_progressValue);
- }
- // TODO: check storage handlers for not existing storages in tree
- for (auto it = m_storageHandlers.cbegin(); it != m_storageHandlers.cend(); ++it) {
- QT_ASSERT(m_storages.contains(it.key()), qWarning("The registered storage doesn't "
- "exist in task tree. Its handlers will never be called."));
- }
- m_runtimeRoot.reset(new RuntimeTask{*m_root});
- startTask(m_runtimeRoot);
- bumpAsyncCount();
-}
-
-void TaskTreePrivate::stop()
-{
- QT_ASSERT(m_root, return);
- if (!m_runtimeRoot)
- return;
- stopTask(m_runtimeRoot.get());
- m_runtimeRoot.reset();
- emitDone(DoneWith::Cancel);
-}
-
-void TaskTreePrivate::bumpAsyncCount()
-{
- if (!m_runtimeRoot)
- return;
- ++m_asyncCount;
- GuardLocker locker(m_guard);
- emit q->asyncCountChanged(m_asyncCount);
-}
-
-void TaskTreePrivate::advanceProgress(int byValue)
-{
- if (byValue == 0)
- return;
- QT_CHECK(byValue > 0);
- QT_CHECK(m_progressValue + byValue <= m_root->taskCount());
- m_progressValue += byValue;
- GuardLocker locker(m_guard);
- emit q->progressValueChanged(m_progressValue);
-}
-
-void TaskTreePrivate::emitDone(DoneWith result)
-{
- QT_CHECK(m_progressValue == m_root->taskCount());
- GuardLocker locker(m_guard);
- emit q->done(result);
-}
-
-RuntimeIteration::RuntimeIteration(int index, RuntimeContainer *container)
- : m_iterationIndex(index)
- , m_isProgressive(index < container->progressiveLoopCount() && isProgressive(container))
- , m_container(container)
-{}
-
-std::optional<Loop> RuntimeIteration::loop() const
-{
- return m_container->m_containerNode.m_loop;
-}
-
-void RuntimeIteration::removeChild(RuntimeTask *task)
-{
- const auto it = std::find_if(m_children.cbegin(), m_children.cend(), [task](const auto &ptr) {
- return ptr.get() == task;
- });
- if (it != m_children.cend())
- m_children.erase(it);
-}
-
-static std::vector<TaskNode> createChildren(TaskTreePrivate *taskTreePrivate,
- const GroupItems &children)
-{
- std::vector<TaskNode> result;
- result.reserve(children.size());
- for (const GroupItem &child : children)
- result.emplace_back(taskTreePrivate, child);
- return result;
-}
-
-ContainerNode::ContainerNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task)
- : m_taskTreePrivate(taskTreePrivate)
- , m_groupHandler(task.m_groupData.m_groupHandler)
- , m_parallelLimit(task.m_groupData.m_parallelLimit.value_or(1))
- , m_workflowPolicy(task.m_groupData.m_workflowPolicy.value_or(WorkflowPolicy::StopOnError))
- , m_loop(task.m_groupData.m_loop)
- , m_storageList(task.m_storageList)
- , m_children(createChildren(taskTreePrivate, task.m_children))
- , m_taskCount(std::accumulate(m_children.cbegin(), m_children.cend(), 0,
- [](int r, const TaskNode &n) { return r + n.taskCount(); })
- * taskTreePrivate->effectiveLoopCount(m_loop))
-{
- for (const StorageBase &storage : m_storageList)
- m_taskTreePrivate->m_storages << storage;
-}
-
-QList<StoragePtr> RuntimeContainer::createStorages(const ContainerNode &container)
-{
- QList<StoragePtr> storages;
- for (const StorageBase &storage : container.m_storageList) {
- StoragePtr storagePtr = storage.m_storageData->m_constructor();
- storages.append(storagePtr);
- container.m_taskTreePrivate->callSetupHandler(storage, storagePtr);
- }
- return storages;
-}
-
-RuntimeIteration *RuntimeContainer::parentIteration() const
-{
- return m_parentTask->m_parentIteration;
-}
-
-bool RuntimeContainer::updateSuccessBit(bool success)
-{
- if (m_containerNode.m_workflowPolicy == WorkflowPolicy::FinishAllAndSuccess
- || m_containerNode.m_workflowPolicy == WorkflowPolicy::FinishAllAndError
- || m_containerNode.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError) {
- if (m_containerNode.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError)
- m_successBit = success;
- return m_successBit;
- }
-
- const bool donePolicy = m_containerNode.m_workflowPolicy == WorkflowPolicy::StopOnSuccess
- || m_containerNode.m_workflowPolicy == WorkflowPolicy::ContinueOnSuccess;
- m_successBit = donePolicy ? (m_successBit || success) : (m_successBit && success);
- return m_successBit;
-}
-
-void RuntimeContainer::deleteFinishedIterations()
-{
- for (auto it = m_iterations.cbegin(); it != m_iterations.cend(); ) {
- if (it->get()->m_doneCount == int(m_containerNode.m_children.size()))
- it = m_iterations.erase(it);
- else
- ++it;
- }
-}
-
-void TaskTreePrivate::continueContainer(RuntimeContainer *container)
-{
- RuntimeTask *parentTask = container->m_parentTask;
- if (parentTask->m_setupResult == SetupResult::Continue)
- startChildren(container);
- if (parentTask->m_setupResult == SetupResult::Continue)
- return;
-
- const bool bit = container->updateSuccessBit(parentTask->m_setupResult == SetupResult::StopWithSuccess);
- RuntimeIteration *parentIteration = container->parentIteration();
- QT_CHECK(parentTask);
- const bool result = invokeDoneHandler(container, bit ? DoneWith::Success : DoneWith::Error);
- parentTask->m_setupResult = toSetupResult(result);
- if (parentIteration) {
- parentIteration->removeChild(parentTask);
- if (!parentIteration->m_container->isStarting())
- childDone(parentIteration, result);
- } else {
- QT_CHECK(m_runtimeRoot.get() == parentTask);
- m_runtimeRoot.reset();
- emitDone(result ? DoneWith::Success : DoneWith::Error);
- }
-}
-
-void TaskTreePrivate::startChildren(RuntimeContainer *container)
-{
- const ContainerNode &containerNode = container->m_containerNode;
- const int childCount = int(containerNode.m_children.size());
-
- if (container->m_iterationCount == 0) {
- if (container->m_shouldIterate && !invokeLoopHandler(container)) {
- if (isProgressive(container))
- advanceProgress(containerNode.m_taskCount);
- container->m_parentTask->m_setupResult = toSetupResult(container->m_successBit);
- return;
- }
- container->m_iterations.emplace_back(
- std::make_unique<RuntimeIteration>(container->m_iterationCount, container));
- ++container->m_iterationCount;
- }
-
- GuardLocker locker(container->m_startGuard);
-
- while (containerNode.m_parallelLimit == 0
- || container->m_runningChildren < containerNode.m_parallelLimit) {
- container->deleteFinishedIterations();
- if (container->m_nextToStart == childCount) {
- if (invokeLoopHandler(container)) {
- container->m_nextToStart = 0;
- container->m_iterations.emplace_back(
- std::make_unique<RuntimeIteration>(container->m_iterationCount, container));
- ++container->m_iterationCount;
- } else if (container->m_iterations.empty()) {
- container->m_parentTask->m_setupResult = toSetupResult(container->m_successBit);
- return;
- } else {
- return;
- }
- }
- if (containerNode.m_children.size() == 0) // Empty loop body.
- continue;
-
- RuntimeIteration *iteration = container->m_iterations.back().get();
- const std::shared_ptr<RuntimeTask> task(
- new RuntimeTask{containerNode.m_children.at(container->m_nextToStart), iteration});
- iteration->m_children.emplace_back(task);
- ++container->m_runningChildren;
- ++container->m_nextToStart;
-
- startTask(task);
- if (task->m_setupResult == SetupResult::Continue)
- continue;
-
- task->m_parentIteration->removeChild(task.get());
- childDone(iteration, task->m_setupResult == SetupResult::StopWithSuccess);
- if (container->m_parentTask->m_setupResult != SetupResult::Continue)
- return;
- }
-}
-
-void TaskTreePrivate::childDone(RuntimeIteration *iteration, bool success)
-{
- RuntimeContainer *container = iteration->m_container;
- const WorkflowPolicy &workflowPolicy = container->m_containerNode.m_workflowPolicy;
- const bool shouldStop = workflowPolicy == WorkflowPolicy::StopOnSuccessOrError
- || (workflowPolicy == WorkflowPolicy::StopOnSuccess && success)
- || (workflowPolicy == WorkflowPolicy::StopOnError && !success);
- ++iteration->m_doneCount;
- --container->m_runningChildren;
- const bool updatedSuccess = container->updateSuccessBit(success);
- container->m_parentTask->m_setupResult = shouldStop ? toSetupResult(updatedSuccess) : SetupResult::Continue;
- if (shouldStop)
- stopContainer(container);
-
- if (container->isStarting())
- return;
- continueContainer(container);
-}
-
-void TaskTreePrivate::stopContainer(RuntimeContainer *container)
-{
- const ContainerNode &containerNode = container->m_containerNode;
- for (auto &iteration : container->m_iterations) {
- for (auto &child : iteration->m_children) {
- ++iteration->m_doneCount;
- stopTask(child.get());
- }
-
- if (iteration->m_isProgressive) {
- int skippedTaskCount = 0;
- for (int i = iteration->m_doneCount; i < int(containerNode.m_children.size()); ++i)
- skippedTaskCount += containerNode.m_children.at(i).taskCount();
- advanceProgress(skippedTaskCount);
- }
- }
- const int skippedIterations = container->progressiveLoopCount() - container->m_iterationCount;
- if (skippedIterations > 0) {
- advanceProgress(container->m_containerNode.m_taskCount / container->progressiveLoopCount()
- * skippedIterations);
- }
-}
-
-static bool shouldCall(CallDoneIf callDoneIf, DoneWith result)
-{
- if (result == DoneWith::Success)
- return callDoneIf != CallDoneIf::Error;
- return callDoneIf != CallDoneIf::Success;
-}
-
-bool TaskTreePrivate::invokeDoneHandler(RuntimeContainer *container, DoneWith doneWith)
-{
- DoneResult result = toDoneResult(doneWith);
- const GroupItem::GroupHandler &groupHandler = container->m_containerNode.m_groupHandler;
- if (groupHandler.m_doneHandler && shouldCall(groupHandler.m_callDoneIf, doneWith))
- result = invokeHandler(container, groupHandler.m_doneHandler, doneWith);
- container->m_callStorageDoneHandlersOnDestruction = true;
- return result == DoneResult::Success;
-}
-
-bool TaskTreePrivate::invokeLoopHandler(RuntimeContainer *container)
-{
- if (container->m_shouldIterate) {
- const LoopData *loopData = container->m_containerNode.m_loop->m_loopData.get();
- if (loopData->m_loopCount) {
- container->m_shouldIterate = container->m_iterationCount < loopData->m_loopCount;
- } else if (loopData->m_condition) {
- container->m_shouldIterate = invokeHandler(container, loopData->m_condition,
- container->m_iterationCount);
- }
- }
- return container->m_shouldIterate;
-}
-
-void TaskTreePrivate::startTask(const std::shared_ptr<RuntimeTask> &node)
-{
- if (!node->m_taskNode.isTask()) {
- const ContainerNode &containerNode = node->m_taskNode.m_container;
- node->m_container.emplace(containerNode, node.get());
- RuntimeContainer *container = &*node->m_container;
- if (containerNode.m_groupHandler.m_setupHandler) {
- container->m_parentTask->m_setupResult = invokeHandler(container, containerNode.m_groupHandler.m_setupHandler);
- if (container->m_parentTask->m_setupResult != SetupResult::Continue) {
- if (isProgressive(container))
- advanceProgress(containerNode.m_taskCount);
- // Non-Continue SetupResult takes precedence over the workflow policy.
- container->m_successBit = container->m_parentTask->m_setupResult == SetupResult::StopWithSuccess;
- }
- }
- continueContainer(container);
- return;
- }
-
- const GroupItem::TaskHandler &handler = node->m_taskNode.m_taskHandler;
- node->m_task.reset(handler.m_createHandler());
- node->m_setupResult = handler.m_setupHandler
- ? invokeHandler(node->m_parentIteration, handler.m_setupHandler, *node->m_task.get())
- : SetupResult::Continue;
- if (node->m_setupResult != SetupResult::Continue) {
- if (node->m_parentIteration->m_isProgressive)
- advanceProgress(1);
- node->m_parentIteration->removeChild(node.get());
- return;
- }
- QObject::connect(node->m_task.get(), &TaskInterface::done,
- q, [this, node](DoneResult doneResult) {
- const bool result = invokeTaskDoneHandler(node.get(), toDoneWith(doneResult));
- node->m_setupResult = toSetupResult(result);
- QObject::disconnect(node->m_task.get(), &TaskInterface::done, q, nullptr);
- node->m_task.release()->deleteLater();
- RuntimeIteration *parentIteration = node->m_parentIteration;
- if (parentIteration->m_container->isStarting())
- return;
-
- parentIteration->removeChild(node.get());
- childDone(parentIteration, result);
- bumpAsyncCount();
- });
- node->m_task->start();
-}
-
-void TaskTreePrivate::stopTask(RuntimeTask *node)
-{
- if (!node->m_task) {
- if (!node->m_container)
- return;
- stopContainer(&*node->m_container);
- node->m_container->updateSuccessBit(false);
- invokeDoneHandler(&*node->m_container, DoneWith::Cancel);
- return;
- }
-
- invokeTaskDoneHandler(node, DoneWith::Cancel);
- node->m_task.reset();
-}
-
-bool TaskTreePrivate::invokeTaskDoneHandler(RuntimeTask *node, DoneWith doneWith)
-{
- DoneResult result = toDoneResult(doneWith);
- const GroupItem::TaskHandler &handler = node->m_taskNode.m_taskHandler;
- if (handler.m_doneHandler && shouldCall(handler.m_callDoneIf, doneWith)) {
- result = invokeHandler(node->m_parentIteration,
- handler.m_doneHandler, *node->m_task.get(), doneWith);
- }
- if (node->m_parentIteration->m_isProgressive)
- advanceProgress(1);
- return result == DoneResult::Success;
-}
-
-/*!
- \class Tasking::TaskTree
- \inheaderfile solutions/tasking/tasktree.h
- \inmodule TaskingSolution
- \brief The TaskTree class runs an async task tree structure defined in a declarative way.
- \reentrant
-
- Use the Tasking namespace to build extensible, declarative task tree
- structures that contain possibly asynchronous tasks, such as QProcess,
- NetworkQuery, or ConcurrentCall<ReturnType>. TaskTree structures enable you
- to create a sophisticated mixture of a parallel or sequential flow of tasks
- in the form of a tree and to run it any time later.
-
- \section1 Root Element and Tasks
-
- The TaskTree has a mandatory Group root element, which may contain
- any number of tasks of various types, such as QProcessTask, NetworkQueryTask,
- or ConcurrentCallTask<ReturnType>:
-
- \code
- using namespace Tasking;
-
- const Group root {
- QProcessTask(...),
- NetworkQueryTask(...),
- ConcurrentCallTask<int>(...)
- };
-
- TaskTree *taskTree = new TaskTree(root);
- connect(taskTree, &TaskTree::done, ...); // finish handler
- taskTree->start();
- \endcode
-
- The task tree above has a top level element of the Group type that contains
- tasks of the QProcessTask, NetworkQueryTask, and ConcurrentCallTask<int> type.
- After taskTree->start() is called, the tasks are run in a chain, starting
- with QProcessTask. When the QProcessTask finishes successfully, the NetworkQueryTask
- task is started. Finally, when the network task finishes successfully, the
- ConcurrentCallTask<int> task is started.
-
- When the last running task finishes with success, the task tree is considered
- to have run successfully and the done() signal is emitted with DoneWith::Success.
- When a task finishes with an error, the execution of the task tree is stopped
- and the remaining tasks are skipped. The task tree finishes with an error and
- sends the TaskTree::done() signal with DoneWith::Error.
-
- \section1 Groups
-
- The parent of the Group sees it as a single task. Like other tasks,
- the group can be started and it can finish with success or an error.
- The Group elements can be nested to create a tree structure:
-
- \code
- const Group root {
- Group {
- parallel,
- QProcessTask(...),
- ConcurrentCallTask<int>(...)
- },
- NetworkQueryTask(...)
- };
- \endcode
-
- The example above differs from the first example in that the root element has
- a subgroup that contains the QProcessTask and ConcurrentCallTask<int>. The subgroup is a
- sibling element of the NetworkQueryTask in the root. The subgroup contains an
- additional \e parallel element that instructs its Group to execute its tasks
- in parallel.
-
- So, when the tree above is started, the QProcessTask and ConcurrentCallTask<int> start
- immediately and run in parallel. Since the root group doesn't contain a
- \e parallel element, its direct child tasks are run in sequence. Thus, the
- NetworkQueryTask starts when the whole subgroup finishes. The group is
- considered as finished when all its tasks have finished. The order in which
- the tasks finish is not relevant.
-
- So, depending on which task lasts longer (QProcessTask or ConcurrentCallTask<int>), the
- following scenarios can take place:
-
- \table
- \header
- \li Scenario 1
- \li Scenario 2
- \row
- \li Root Group starts
- \li Root Group starts
- \row
- \li Sub Group starts
- \li Sub Group starts
- \row
- \li QProcessTask starts
- \li QProcessTask starts
- \row
- \li ConcurrentCallTask<int> starts
- \li ConcurrentCallTask<int> starts
- \row
- \li ...
- \li ...
- \row
- \li \b {QProcessTask finishes}
- \li \b {ConcurrentCallTask<int> finishes}
- \row
- \li ...
- \li ...
- \row
- \li \b {ConcurrentCallTask<int> finishes}
- \li \b {QProcessTask finishes}
- \row
- \li Sub Group finishes
- \li Sub Group finishes
- \row
- \li NetworkQueryTask starts
- \li NetworkQueryTask starts
- \row
- \li ...
- \li ...
- \row
- \li NetworkQueryTask finishes
- \li NetworkQueryTask finishes
- \row
- \li Root Group finishes
- \li Root Group finishes
- \endtable
-
- The differences between the scenarios are marked with bold. Three dots mean
- that an unspecified amount of time passes between previous and next events
- (a task or tasks continue to run). No dots between events
- means that they occur synchronously.
-
- The presented scenarios assume that all tasks run successfully. If a task
- fails during execution, the task tree finishes with an error. In particular,
- when QProcessTask finishes with an error while ConcurrentCallTask<int> is still being executed,
- the ConcurrentCallTask<int> is automatically canceled, the subgroup finishes with an error,
- the NetworkQueryTask is skipped, and the tree finishes with an error.
-
- \section1 Task Types
-
- Each task type is associated with its corresponding task class that executes
- the task. For example, a QProcessTask inside a task tree is associated with
- the QProcess class that executes the process. The associated objects are
- automatically created, started, and destructed exclusively by the task tree
- at the appropriate time.
-
- If a root group consists of five sequential QProcessTask tasks, and the task tree
- executes the group, it creates an instance of QProcess for the first
- QProcessTask and starts it. If the QProcess instance finishes successfully,
- the task tree destructs it and creates a new QProcess instance for the
- second QProcessTask, and so on. If the first task finishes with an error, the task
- tree stops creating QProcess instances, and the root group finishes with an
- error.
-
- The following table shows examples of task types and their corresponding task
- classes:
-
- \table
- \header
- \li Task Type (Tasking Namespace)
- \li Associated Task Class
- \li Brief Description
- \row
- \li QProcessTask
- \li QProcess
- \li Starts process.
- \row
- \li ConcurrentCallTask<ReturnType>
- \li Tasking::ConcurrentCall<ReturnType>
- \li Starts asynchronous task, runs in separate thread.
- \row
- \li TaskTreeTask
- \li Tasking::TaskTree
- \li Starts nested task tree.
- \row
- \li NetworkQueryTask
- \li NetworkQuery
- \li Starts network download.
- \endtable
-
- \section1 Task Handlers
-
- Use Task handlers to set up a task for execution and to enable reading
- the output data from the task when it finishes with success or an error.
-
- \section2 Task's Start Handler
-
- When a corresponding task class object is created and before it's started,
- the task tree invokes an optionally user-provided setup handler. The setup
- handler should always take a \e reference to the associated task class object:
-
- \code
- const auto onSetup = [](QProcess &process) {
- process.setProgram("sleep");
- process.setArguments({"3"});
- };
- const Group root {
- QProcessTask(onSetup)
- };
- \endcode
-
- You can modify the passed QProcess in the setup handler, so that the task
- tree can start the process according to your configuration.
- You should not call \c {process.start();} in the setup handler,
- as the task tree calls it when needed. The setup handler is optional. When used,
- it must be the first argument of the task's constructor.
-
- Optionally, the setup handler may return a SetupResult. The returned
- SetupResult influences the further start behavior of a given task. The
- possible values are:
-
- \table
- \header
- \li SetupResult Value
- \li Brief Description
- \row
- \li Continue
- \li The task will be started normally. This is the default behavior when the
- setup handler doesn't return SetupResult (that is, its return type is
- void).
- \row
- \li StopWithSuccess
- \li The task won't be started and it will report success to its parent.
- \row
- \li StopWithError
- \li The task won't be started and it will report an error to its parent.
- \endtable
-
- This is useful for running a task only when a condition is met and the data
- needed to evaluate this condition is not known until previously started tasks
- finish. In this way, the setup handler dynamically decides whether to start the
- corresponding task normally or skip it and report success or an error.
- For more information about inter-task data exchange, see \l Storage.
-
- \section2 Task's Done Handler
-
- When a running task finishes, the task tree invokes an optionally provided done handler.
- The handler should take a \c const \e reference to the associated task class object:
-
- \code
- const auto onSetup = [](QProcess &process) {
- process.setProgram("sleep");
- process.setArguments({"3"});
- };
- const auto onDone = [](const QProcess &process, DoneWith result) {
- if (result == DoneWith::Success)
- qDebug() << "Success" << process.cleanedStdOut();
- else
- qDebug() << "Failure" << process.cleanedStdErr();
- };
- const Group root {
- QProcessTask(onSetup, onDone)
- };
- \endcode
-
- The done handler may collect output data from QProcess, and store it
- for further processing or perform additional actions.
-
- \note If the task setup handler returns StopWithSuccess or StopWithError,
- the done handler is not invoked.
-
- \section1 Group Handlers
-
- Similarly to task handlers, group handlers enable you to set up a group to
- execute and to apply more actions when the whole group finishes with
- success or an error.
-
- \section2 Group's Start Handler
-
- The task tree invokes the group start handler before it starts the child
- tasks. The group handler doesn't take any arguments:
-
- \code
- const auto onSetup = [] {
- qDebug() << "Entering the group";
- };
- const Group root {
- onGroupSetup(onSetup),
- QProcessTask(...)
- };
- \endcode
-
- The group setup handler is optional. To define a group setup handler, add an
- onGroupSetup() element to a group. The argument of onGroupSetup() is a user
- handler. If you add more than one onGroupSetup() element to a group, an assert
- is triggered at runtime that includes an error message.
-
- Like the task's start handler, the group start handler may return SetupResult.
- The returned SetupResult value affects the start behavior of the
- whole group. If you do not specify a group start handler or its return type
- is void, the default group's action is SetupResult::Continue, so that all
- tasks are started normally. Otherwise, when the start handler returns
- SetupResult::StopWithSuccess or SetupResult::StopWithError, the tasks are not
- started (they are skipped) and the group itself reports success or failure,
- depending on the returned value, respectively.
-
- \code
- const Group root {
- onGroupSetup([] { qDebug() << "Root setup"; }),
- Group {
- onGroupSetup([] { qDebug() << "Group 1 setup"; return SetupResult::Continue; }),
- QProcessTask(...) // Process 1
- },
- Group {
- onGroupSetup([] { qDebug() << "Group 2 setup"; return SetupResult::StopWithSuccess; }),
- QProcessTask(...) // Process 2
- },
- Group {
- onGroupSetup([] { qDebug() << "Group 3 setup"; return SetupResult::StopWithError; }),
- QProcessTask(...) // Process 3
- },
- QProcessTask(...) // Process 4
- };
- \endcode
-
- In the above example, all subgroups of a root group define their setup handlers.
- The following scenario assumes that all started processes finish with success:
-
- \table
- \header
- \li Scenario
- \li Comment
- \row
- \li Root Group starts
- \li Doesn't return SetupResult, so its tasks are executed.
- \row
- \li Group 1 starts
- \li Returns Continue, so its tasks are executed.
- \row
- \li Process 1 starts
- \li
- \row
- \li ...
- \li ...
- \row
- \li Process 1 finishes (success)
- \li
- \row
- \li Group 1 finishes (success)
- \li
- \row
- \li Group 2 starts
- \li Returns StopWithSuccess, so Process 2 is skipped and Group 2 reports
- success.
- \row
- \li Group 2 finishes (success)
- \li
- \row
- \li Group 3 starts
- \li Returns StopWithError, so Process 3 is skipped and Group 3 reports
- an error.
- \row
- \li Group 3 finishes (error)
- \li
- \row
- \li Root Group finishes (error)
- \li Group 3, which is a direct child of the root group, finished with an
- error, so the root group stops executing, skips Process 4, which has
- not started yet, and reports an error.
- \endtable
-
- \section2 Groups's Done Handler
-
- A Group's done handler is executed after the successful or failed execution of its tasks.
- The final value reported by the group depends on its \l {Workflow Policy}.
- The handler can apply other necessary actions.
- The done handler is defined inside the onGroupDone() element of a group.
- It may take the optional DoneWith argument, indicating the successful or failed execution:
-
- \code
- const Group root {
- onGroupSetup([] { qDebug() << "Root setup"; }),
- QProcessTask(...),
- onGroupDone([](DoneWith result) {
- if (result == DoneWith::Success)
- qDebug() << "Root finished with success";
- else
- qDebug() << "Root finished with an error";
- })
- };
- \endcode
-
- The group done handler is optional. If you add more than one onGroupDone() to a group,
- an assert is triggered at runtime that includes an error message.
-
- \note Even if the group setup handler returns StopWithSuccess or StopWithError,
- the group's done handler is invoked. This behavior differs from that of task done handler
- and might change in the future.
-
- \section1 Other Group Elements
-
- A group can contain other elements that describe the processing flow, such as
- the execution mode or workflow policy. It can also contain storage elements
- that are responsible for collecting and sharing custom common data gathered
- during group execution.
-
- \section2 Execution Mode
-
- The execution mode element in a Group specifies how the direct child tasks of
- the Group are started. The most common execution modes are \l sequential and
- \l parallel. It's also possible to specify the limit of tasks running
- in parallel by using the parallelLimit() function.
-
- In all execution modes, a group starts tasks in the oder in which they appear.
-
- If a child of a group is also a group, the child group runs its tasks
- according to its own execution mode.
-
- \section2 Workflow Policy
-
- The workflow policy element in a Group specifies how the group should behave
- when any of its \e direct child's tasks finish. For a detailed description of possible
- policies, refer to WorkflowPolicy.
-
- If a child of a group is also a group, the child group runs its tasks
- according to its own workflow policy.
-
- \section2 Storage
-
- Use the \l {Tasking::Storage} {Storage} element to exchange information between tasks.
- Especially, in the sequential execution mode, when a task needs data from another,
- already finished task, before it can start. For example, a task tree that copies data by reading
- it from a source and writing it to a destination might look as follows:
-
- \code
- static QByteArray load(const QString &fileName) { ... }
- static void save(const QString &fileName, const QByteArray &array) { ... }
-
- static Group copyRecipe(const QString &source, const QString &destination)
- {
- struct CopyStorage { // [1] custom inter-task struct
- QByteArray content; // [2] custom inter-task data
- };
-
- // [3] instance of custom inter-task struct manageable by task tree
- const Storage<CopyStorage> storage;
-
- const auto onLoaderSetup = [source](ConcurrentCall<QByteArray> &async) {
- async.setConcurrentCallData(&load, source);
- };
- // [4] runtime: task tree activates the instance from [7] before invoking handler
- const auto onLoaderDone = [storage](const ConcurrentCall<QByteArray> &async) {
- storage->content = async.result(); // [5] loader stores the result in storage
- };
-
- // [4] runtime: task tree activates the instance from [7] before invoking handler
- const auto onSaverSetup = [storage, destination](ConcurrentCall<void> &async) {
- const QByteArray content = storage->content; // [6] saver takes data from storage
- async.setConcurrentCallData(&save, destination, content);
- };
- const auto onSaverDone = [](const ConcurrentCall<void> &async) {
- qDebug() << "Save done successfully";
- };
-
- const Group root {
- // [7] runtime: task tree creates an instance of CopyStorage when root is entered
- storage,
- ConcurrentCallTask<QByteArray>(onLoaderSetup, onLoaderDone, CallDoneIf::Success),
- ConcurrentCallTask<void>(onSaverSetup, onSaverDone, CallDoneIf::Success)
- };
- return root;
- }
-
- const QString source = ...;
- const QString destination = ...;
- TaskTree taskTree(copyRecipe(source, destination));
- connect(&taskTree, &TaskTree::done,
- &taskTree, [](DoneWith result) {
- if (result == DoneWith::Success)
- qDebug() << "The copying finished successfully.";
- });
- tasktree.start();
- \endcode
-
- In the example above, the inter-task data consists of a QByteArray content
- variable [2] enclosed in a \c CopyStorage custom struct [1]. If the loader
- finishes successfully, it stores the data in a \c CopyStorage::content
- variable [5]. The saver then uses the variable to configure the saving task [6].
-
- To enable a task tree to manage the \c CopyStorage struct, an instance of
- \l {Tasking::Storage} {Storage}<\c CopyStorage> is created [3]. If a copy of this object is
- inserted as the group's child item [7], an instance of the \c CopyStorage struct is
- created dynamically when the task tree enters this group. When the task
- tree leaves this group, the existing instance of the \c CopyStorage struct is
- destructed as it's no longer needed.
-
- If several task trees holding a copy of the common
- \l {Tasking::Storage} {Storage}<\c CopyStorage> instance run simultaneously
- (including the case when the task trees are run in different threads),
- each task tree contains its own copy of the \c CopyStorage struct.
-
- You can access \c CopyStorage from any handler in the group with a storage object.
- This includes all handlers of all descendant tasks of the group with
- a storage object. To access the custom struct in a handler, pass the
- copy of the \l {Tasking::Storage} {Storage}<\c CopyStorage> object to the handler
- (for example, in a lambda capture) [4].
-
- When the task tree invokes a handler in a subtree containing the storage [7],
- the task tree activates its own \c CopyStorage instance inside the
- \l {Tasking::Storage} {Storage}<\c CopyStorage> object. Therefore, the \c CopyStorage struct
- may be accessed only from within the handler body. To access the currently active
- \c CopyStorage from within \l {Tasking::Storage} {Storage}<\c CopyStorage>, use the
- \l {Tasking::Storage::operator->()} {Storage::operator->()},
- \l {Tasking::Storage::operator*()} {Storage::operator*()}, or Storage::activeStorage() method.
-
- The following list summarizes how to employ a Storage object into the task
- tree:
- \list 1
- \li Define the custom structure \c MyStorage with custom data [1], [2]
- \li Create an instance of the \l {Tasking::Storage} {Storage}<\c MyStorage> storage [3]
- \li Pass the \l {Tasking::Storage} {Storage}<\c MyStorage> instance to handlers [4]
- \li Access the \c MyStorage instance in handlers [5], [6]
- \li Insert the \l {Tasking::Storage} {Storage}<\c MyStorage> instance into a group [7]
- \endlist
-
- \section1 TaskTree class
-
- TaskTree executes the tree structure of asynchronous tasks according to the
- recipe described by the Group root element.
-
- As TaskTree is also an asynchronous task, it can be a part of another TaskTree.
- To place a nested TaskTree inside another TaskTree, insert the TaskTreeTask
- element into another Group element.
-
- TaskTree reports progress of completed tasks when running. The progress value
- is increased when a task finishes or is skipped or canceled.
- When TaskTree is finished and the TaskTree::done() signal is emitted,
- the current value of the progress equals the maximum progress value.
- Maximum progress equals the total number of asynchronous tasks in a tree.
- A nested TaskTree is counted as a single task, and its child tasks are not
- counted in the top level tree. Groups themselves are not counted as tasks,
- but their tasks are counted. \l {Tasking::Sync} {Sync} tasks are not asynchronous,
- so they are not counted as tasks.
-
- To set additional initial data for the running tree, modify the storage
- instances in a tree when it creates them by installing a storage setup
- handler:
-
- \code
- Storage<CopyStorage> storage;
- const Group root = ...; // storage placed inside root's group and inside handlers
- TaskTree taskTree(root);
- auto initStorage = [](CopyStorage &storage) {
- storage.content = "initial content";
- };
- taskTree.onStorageSetup(storage, initStorage);
- taskTree.start();
- \endcode
-
- When the running task tree creates a \c CopyStorage instance, and before any
- handler inside a tree is called, the task tree calls the initStorage handler,
- to enable setting up initial data of the storage, unique to this particular
- run of taskTree.
-
- Similarly, to collect some additional result data from the running tree,
- read it from storage instances in the tree when they are about to be
- destroyed. To do this, install a storage done handler:
-
- \code
- Storage<CopyStorage> storage;
- const Group root = ...; // storage placed inside root's group and inside handlers
- TaskTree taskTree(root);
- auto collectStorage = [](const CopyStorage &storage) {
- qDebug() << "final content" << storage.content;
- };
- taskTree.onStorageDone(storage, collectStorage);
- taskTree.start();
- \endcode
-
- When the running task tree is about to destroy a \c CopyStorage instance, the
- task tree calls the collectStorage handler, to enable reading the final data
- from the storage, unique to this particular run of taskTree.
-
- \section1 Task Adapters
-
- To extend a TaskTree with a new task type, implement a simple adapter class
- derived from the TaskAdapter class template. The following class is an
- adapter for a single shot timer, which may be considered as a new asynchronous task:
-
- \code
- class TimerTaskAdapter : public TaskAdapter<QTimer>
- {
- public:
- TimerTaskAdapter() {
- task()->setSingleShot(true);
- task()->setInterval(1000);
- connect(task(), &QTimer::timeout, this, [this] { emit done(DoneResult::Success); });
- }
- private:
- void start() final { task()->start(); }
- };
-
- using TimerTask = CustomTask<TimerTaskAdapter>;
- \endcode
-
- You must derive the custom adapter from the TaskAdapter class template
- instantiated with a template parameter of the class implementing a running
- task. The code above uses QTimer to run the task. This class appears
- later as an argument to the task's handlers. The instance of this class
- parameter automatically becomes a member of the TaskAdapter template, and is
- accessible through the TaskAdapter::task() method. The constructor
- of \c TimerTaskAdapter initially configures the QTimer object and connects
- to the QTimer::timeout() signal. When the signal is triggered, \c TimerTaskAdapter
- emits the TaskInterface::done(DoneResult::Success) signal to inform the task tree that
- the task finished successfully. If it emits TaskInterface::done(DoneResult::Error),
- the task finished with an error.
- The TaskAdapter::start() method starts the timer.
-
- To make QTimer accessible inside TaskTree under the \c TimerTask name,
- define \c TimerTask to be an alias to the CustomTask<\c TimerTaskAdapter>.
- \c TimerTask becomes a new custom task type, using \c TimerTaskAdapter.
-
- The new task type is now registered, and you can use it in TaskTree:
-
- \code
- const auto onSetup = [](QTimer &task) { task.setInterval(2000); };
- const auto onDone = [] { qDebug() << "timer triggered"; };
- const Group root {
- TimerTask(onSetup, onDone)
- };
- \endcode
-
- When a task tree containing the root from the above example is started, it
- prints a debug message within two seconds and then finishes successfully.
-
- \note The class implementing the running task should have a default constructor,
- and objects of this class should be freely destructible. It should be allowed
- to destroy a running object, preferably without waiting for the running task
- to finish (that is, safe non-blocking destructor of a running task).
- To achieve a non-blocking destruction of a task that has a blocking destructor,
- consider using the optional \c Deleter template parameter of the TaskAdapter.
-*/
-
-/*!
- Constructs an empty task tree. Use setRecipe() to pass a declarative description
- on how the task tree should execute the tasks and how it should handle the finished tasks.
-
- Starting an empty task tree is no-op and the relevant warning message is issued.
-
- \sa setRecipe(), start()
-*/
-TaskTree::TaskTree()
- : d(new TaskTreePrivate(this))
-{}
-
-/*!
- \overload
-
- Constructs a task tree with a given \a recipe. After the task tree is started,
- it executes the tasks contained inside the \a recipe and
- handles finished tasks according to the passed description.
-
- \sa setRecipe(), start()
-*/
-TaskTree::TaskTree(const Group &recipe) : TaskTree()
-{
- setRecipe(recipe);
-}
-
-/*!
- Destroys the task tree.
-
- When the task tree is running while being destructed, it cancels all the running tasks
- immediately. In this case, no handlers are called, not even the groups' and
- tasks' done handlers or onStorageDone() handlers. The task tree also doesn't emit any
- signals from the destructor, not even done() or progressValueChanged() signals.
- This behavior may always be relied on.
- It is completely safe to destruct the running task tree.
-
- It's a usual pattern to destruct the running task tree.
- It's guaranteed that the destruction will run quickly, without having to wait for
- the currently running tasks to finish, provided that the used tasks implement
- their destructors in a non-blocking way.
-
- \note Do not call the destructor directly from any of the running task's handlers
- or task tree's signals. In these cases, use \l deleteLater() instead.
-
- \sa cancel()
-*/
-TaskTree::~TaskTree()
-{
- QT_ASSERT(!d->m_guard.isLocked(), qWarning("Deleting TaskTree instance directly from "
- "one of its handlers will lead to a crash!"));
- // TODO: delete storages explicitly here?
- delete d;
-}
-
-/*!
- Sets a given \a recipe for the task tree. After the task tree is started,
- it executes the tasks contained inside the \a recipe and
- handles finished tasks according to the passed description.
-
- \note When called for a running task tree, the call is ignored.
-
- \sa TaskTree(const Tasking::Group &recipe), start()
-*/
-void TaskTree::setRecipe(const Group &recipe)
-{
- QT_ASSERT(!isRunning(), qWarning("The TaskTree is already running, ignoring..."); return);
- QT_ASSERT(!d->m_guard.isLocked(), qWarning("The setRecipe() is called from one of the"
- "TaskTree handlers, ignoring..."); return);
- // TODO: Should we clear the m_storageHandlers, too?
- d->m_storages.clear();
- d->m_root.emplace(d, recipe);
-}
-
-/*!
- Starts the task tree.
-
- Use setRecipe() or the constructor to set the declarative description according to which
- the task tree will execute the contained tasks and handle finished tasks.
-
- When the task tree is empty, that is, constructed with a default constructor,
- a call to \c start() is no-op and the relevant warning message is issued.
-
- Otherwise, when the task tree is already running, a call to \e start() is ignored and the
- relevant warning message is issued.
-
- Otherwise, the task tree is started.
-
- The started task tree may finish synchronously,
- for example when the main group's start handler returns SetupResult::StopWithError.
- For this reason, the connection to the done signal should be established before calling
- \c start(). Use isRunning() in order to detect whether the task tree is still running
- after a call to \c start().
-
- The task tree implementation relies on the running event loop.
- Make sure you have a QEventLoop or QCoreApplication or one of its
- subclasses running (or about to be run) when calling this method.
-
- \sa TaskTree(const Tasking::Group &), setRecipe(), isRunning(), cancel()
-*/
-void TaskTree::start()
-{
- QT_ASSERT(!isRunning(), qWarning("The TaskTree is already running, ignoring..."); return);
- QT_ASSERT(!d->m_guard.isLocked(), qWarning("The start() is called from one of the"
- "TaskTree handlers, ignoring..."); return);
- d->start();
-}
-
-/*!
- \fn void TaskTree::started()
-
- This signal is emitted when the task tree is started. The emission of this signal is
- followed synchronously by the progressValueChanged() signal with an initial \c 0 value.
-
- \sa start(), done()
-*/
-
-/*!
- \fn void TaskTree::done(DoneWith result)
-
- This signal is emitted when the task tree finished, passing the final \a result
- of the execution. The task tree neither calls any handler,
- nor emits any signal anymore after this signal was emitted.
-
- \note Do not delete the task tree directly from this signal's handler.
- Use deleteLater() instead.
-
- \sa started()
-*/
-
-/*!
- Cancels the execution of the running task tree.
-
- Cancels all the running tasks immediately.
- All running tasks finish with an error, invoking their error handlers.
- All running groups dispatch their handlers according to their workflow policies,
- invoking their done handlers. The storages' onStorageDone() handlers are invoked, too.
- The progressValueChanged() signals are also being sent.
- This behavior may always be relied on.
-
- The \c cancel() function is executed synchronously, so that after a call to \c cancel()
- all running tasks are finished and the tree is already canceled.
- It's guaranteed that \c cancel() will run quickly, without any blocking wait for
- the currently running tasks to finish, provided the used tasks implement their destructors
- in a non-blocking way.
-
- When the task tree is empty, that is, constructed with a default constructor,
- a call to \c cancel() is no-op and the relevant warning message is issued.
-
- Otherwise, when the task tree wasn't started, a call to \c cancel() is ignored.
-
- \note Do not call this function directly from any of the running task's handlers
- or task tree's signals.
-
- \sa ~TaskTree()
-*/
-void TaskTree::cancel()
-{
- QT_ASSERT(!d->m_guard.isLocked(), qWarning("The cancel() is called from one of the"
- "TaskTree handlers, ignoring..."); return);
- d->stop();
-}
-
-/*!
- Returns \c true if the task tree is currently running; otherwise returns \c false.
-
- \sa start(), cancel()
-*/
-bool TaskTree::isRunning() const
-{
- return bool(d->m_runtimeRoot);
-}
-
-/*!
- Executes a local event loop with QEventLoop::ExcludeUserInputEvents and starts the task tree.
-
- Returns DoneWith::Success if the task tree finished successfully;
- otherwise returns DoneWith::Error.
-
- \note Avoid using this method from the main thread. Use asynchronous start() instead.
- This method is to be used in non-main threads or in auto tests.
-
- \sa start()
-*/
-DoneWith TaskTree::runBlocking()
-{
- QPromise<void> dummy;
- dummy.start();
- return runBlocking(dummy.future());
-}
-
-/*!
- \overload runBlocking()
-
- The passed \a future is used for listening to the cancel event.
- When the task tree is canceled, this method cancels the passed \a future.
-*/
-DoneWith TaskTree::runBlocking(const QFuture<void> &future)
-{
- if (future.isCanceled())
- return DoneWith::Cancel;
-
- DoneWith doneWith = DoneWith::Cancel;
- QEventLoop loop;
- connect(this, &TaskTree::done, &loop, [&loop, &doneWith](DoneWith result) {
- doneWith = result;
- // Otherwise, the tasks from inside the running tree that were deleteLater()
- // will be leaked. Refer to the QObject::deleteLater() docs.
- QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection);
- });
- QFutureWatcher<void> watcher;
- connect(&watcher, &QFutureWatcherBase::canceled, this, &TaskTree::cancel);
- watcher.setFuture(future);
-
- QTimer::singleShot(0, this, &TaskTree::start);
-
- loop.exec(QEventLoop::ExcludeUserInputEvents);
- if (doneWith == DoneWith::Cancel) {
- auto nonConstFuture = future;
- nonConstFuture.cancel();
- }
- return doneWith;
-}
-
-/*!
- Constructs a temporary task tree using the passed \a recipe and runs it blocking.
-
- Returns DoneWith::Success if the task tree finished successfully;
- otherwise returns DoneWith::Error.
-
- \note Avoid using this method from the main thread. Use asynchronous start() instead.
- This method is to be used in non-main threads or in auto tests.
-
- \sa start()
-*/
-DoneWith TaskTree::runBlocking(const Group &recipe)
-{
- QPromise<void> dummy;
- dummy.start();
- return TaskTree::runBlocking(recipe, dummy.future());
-}
-
-/*!
- \overload runBlocking(const Group &recipe)
-
- The passed \a future is used for listening to the cancel event.
- When the task tree is canceled, this method cancels the passed \a future.
-*/
-DoneWith TaskTree::runBlocking(const Group &recipe, const QFuture<void> &future)
-{
- TaskTree taskTree(recipe);
- return taskTree.runBlocking(future);
-}
-
-/*!
- Returns the current real count of asynchronous chains of invocations.
-
- The returned value indicates how many times the control returns to the caller's
- event loop while the task tree is running. Initially, this value is 0.
- If the execution of the task tree finishes fully synchronously, this value remains 0.
- If the task tree contains any asynchronous tasks that are successfully started during
- a call to start(), this value is bumped to 1 just before the call to start() finishes.
- Later, when any asynchronous task finishes and any possible continuations are started,
- this value is bumped again. The bumping continues until the task tree finishes.
- When the task tree emits the done() signal, the bumping stops.
- The asyncCountChanged() signal is emitted on every bump of this value.
-
- \sa asyncCountChanged()
-*/
-int TaskTree::asyncCount() const
-{
- return d->m_asyncCount;
-}
-
-/*!
- \fn void TaskTree::asyncCountChanged(int count)
-
- This signal is emitted when the running task tree is about to return control to the caller's
- event loop. When the task tree is started, this signal is emitted with \a count value of 0,
- and emitted later on every asyncCount() value bump with an updated \a count value.
- Every signal sent (except the initial one with the value of 0) guarantees that the task tree
- is still running asynchronously after the emission.
-
- \sa asyncCount()
-*/
-
-/*!
- Returns the number of asynchronous tasks contained in the stored recipe.
-
- \note The returned number doesn't include \l {Tasking::Sync} {Sync} tasks.
- \note Any task or group that was set up using withTimeout() increases the total number of
- tasks by \c 1.
-
- \sa setRecipe(), progressMaximum()
-*/
-int TaskTree::taskCount() const
-{
- return d->m_root ? d->m_root->taskCount() : 0;
-}
-
-/*!
- \fn void TaskTree::progressValueChanged(int value)
-
- This signal is emitted when the running task tree finished, canceled, or skipped some tasks.
- The \a value gives the current total number of finished, canceled or skipped tasks.
- When the task tree is started, and after the started() signal was emitted,
- this signal is emitted with an initial \a value of \c 0.
- When the task tree is about to finish, and before the done() signal is emitted,
- this signal is emitted with the final \a value of progressMaximum().
-
- \sa progressValue(), progressMaximum()
-*/
-
-/*!
- \fn int TaskTree::progressMaximum() const
-
- Returns the maximum progressValue().
-
- \note Currently, it's the same as taskCount(). This might change in the future.
-
- \sa progressValue()
-*/
-
-/*!
- Returns the current progress value, which is between the \c 0 and progressMaximum().
-
- The returned number indicates how many tasks have been already finished, canceled, or skipped
- while the task tree is running.
- When the task tree is started, this number is set to \c 0.
- When the task tree is finished, this number always equals progressMaximum().
-
- \sa progressMaximum(), progressValueChanged()
-*/
-int TaskTree::progressValue() const
-{
- return d->m_progressValue;
-}
-
-/*!
- \fn template <typename StorageStruct, typename Handler> void TaskTree::onStorageSetup(const Storage<StorageStruct> &storage, Handler &&handler)
-
- Installs a storage setup \a handler for the \a storage to pass the initial data
- dynamically to the running task tree.
-
- The \c StorageHandler takes a \e reference to the \c StorageStruct instance:
-
- \code
- static void save(const QString &fileName, const QByteArray &array) { ... }
-
- Storage<QByteArray> storage;
-
- const auto onSaverSetup = [storage](ConcurrentCall<QByteArray> &concurrent) {
- concurrent.setConcurrentCallData(&save, "foo.txt", *storage);
- };
-
- const Group root {
- storage,
- ConcurrentCallTask(onSaverSetup)
- };
-
- TaskTree taskTree(root);
- auto initStorage = [](QByteArray &storage){
- storage = "initial content";
- };
- taskTree.onStorageSetup(storage, initStorage);
- taskTree.start();
- \endcode
-
- When the running task tree enters a Group where the \a storage is placed in,
- it creates a \c StorageStruct instance, ready to be used inside this group.
- Just after the \c StorageStruct instance is created, and before any handler of this group
- is called, the task tree invokes the passed \a handler. This enables setting up
- initial content for the given storage dynamically. Later, when any group's handler is invoked,
- the task tree activates the created and initialized storage, so that it's available inside
- any group's handler.
-
- \sa onStorageDone()
-*/
-
-/*!
- \fn template <typename StorageStruct, typename Handler> void TaskTree::onStorageDone(const Storage<StorageStruct> &storage, Handler &&handler)
-
- Installs a storage done \a handler for the \a storage to retrieve the final data
- dynamically from the running task tree.
-
- The \c StorageHandler takes a \c const \e reference to the \c StorageStruct instance:
-
- \code
- static QByteArray load(const QString &fileName) { ... }
-
- Storage<QByteArray> storage;
-
- const auto onLoaderSetup = [](ConcurrentCall<QByteArray> &concurrent) {
- concurrent.setConcurrentCallData(&load, "foo.txt");
- };
- const auto onLoaderDone = [storage](const ConcurrentCall<QByteArray> &concurrent) {
- *storage = concurrent.result();
- };
-
- const Group root {
- storage,
- ConcurrentCallTask(onLoaderSetup, onLoaderDone, CallDoneIf::Success)
- };
-
- TaskTree taskTree(root);
- auto collectStorage = [](const QByteArray &storage){
- qDebug() << "final content" << storage;
- };
- taskTree.onStorageDone(storage, collectStorage);
- taskTree.start();
- \endcode
-
- When the running task tree is about to leave a Group where the \a storage is placed in,
- it destructs a \c StorageStruct instance.
- Just before the \c StorageStruct instance is destructed, and after all possible handlers from
- this group were called, the task tree invokes the passed \a handler. This enables reading
- the final content of the given storage dynamically and processing it further outside of
- the task tree.
-
- This handler is called also when the running tree is canceled. However, it's not called
- when the running tree is destructed.
-
- \sa onStorageSetup()
-*/
-
-void TaskTree::setupStorageHandler(const StorageBase &storage,
- const StorageBase::StorageHandler &setupHandler,
- const StorageBase::StorageHandler &doneHandler)
-{
- auto it = d->m_storageHandlers.find(storage);
- if (it == d->m_storageHandlers.end()) {
- d->m_storageHandlers.insert(storage, {setupHandler, doneHandler});
- return;
- }
- if (setupHandler) {
- QT_ASSERT(!it->m_setupHandler,
- qWarning("The storage has its setup handler defined, overriding..."));
- it->m_setupHandler = setupHandler;
- }
- if (doneHandler) {
- QT_ASSERT(!it->m_doneHandler,
- qWarning("The storage has its done handler defined, overriding..."));
- it->m_doneHandler = doneHandler;
- }
-}
-
-TaskTreeTaskAdapter::TaskTreeTaskAdapter()
-{
- connect(task(), &TaskTree::done, this,
- [this](DoneWith result) { emit done(toDoneResult(result)); });
-}
-
-void TaskTreeTaskAdapter::start()
-{
- task()->start();
-}
-
-using TimeoutCallback = std::function<void()>;
-
-struct TimerData
-{
- system_clock::time_point m_deadline;
- QPointer<QObject> m_context;
- TimeoutCallback m_callback;
-};
-
-struct TimerThreadData
-{
- Q_DISABLE_COPY_MOVE(TimerThreadData)
-
- TimerThreadData() = default; // defult constructor is required for initializing with {} since C++20 by Mingw 11.20
- QHash<int, TimerData> m_timerIdToTimerData = {};
- QMap<system_clock::time_point, QList<int>> m_deadlineToTimerId = {};
- int m_timerIdCounter = 0;
-};
-
-// Please note the thread_local keyword below guarantees a separate instance per thread.
-static thread_local TimerThreadData s_threadTimerData = {};
-
-static void removeTimerId(int timerId)
-{
- const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(timerId);
- QT_ASSERT(it != s_threadTimerData.m_timerIdToTimerData.cend(),
- qWarning("Removing active timerId failed."); return);
-
- const system_clock::time_point deadline = it->m_deadline;
- s_threadTimerData.m_timerIdToTimerData.erase(it);
-
- QList<int> &ids = s_threadTimerData.m_deadlineToTimerId[deadline];
- const int removedCount = ids.removeAll(timerId);
- QT_ASSERT(removedCount == 1, qWarning("Removing active timerId failed."); return);
- if (ids.isEmpty())
- s_threadTimerData.m_deadlineToTimerId.remove(deadline);
-}
-
-static void handleTimeout(int timerId)
-{
- const auto itData = s_threadTimerData.m_timerIdToTimerData.constFind(timerId);
- if (itData == s_threadTimerData.m_timerIdToTimerData.cend())
- return; // The timer was already activated.
-
- const auto deadline = itData->m_deadline;
- while (true) {
- auto itMap = s_threadTimerData.m_deadlineToTimerId.begin();
- if (itMap == s_threadTimerData.m_deadlineToTimerId.end())
- return;
-
- if (itMap.key() > deadline)
- return;
-
- std::optional<TimerData> timerData;
- QList<int> &idList = *itMap;
- if (!idList.isEmpty()) {
- const int first = idList.first();
- idList.removeFirst();
-
- const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(first);
- if (it != s_threadTimerData.m_timerIdToTimerData.cend()) {
- timerData = it.value();
- s_threadTimerData.m_timerIdToTimerData.erase(it);
- } else {
- QT_CHECK(false);
- }
- } else {
- QT_CHECK(false);
- }
-
- if (idList.isEmpty())
- s_threadTimerData.m_deadlineToTimerId.erase(itMap);
- if (timerData && timerData->m_context)
- timerData->m_callback();
- }
-}
-
-static int scheduleTimeout(milliseconds timeout, QObject *context, const TimeoutCallback &callback)
-{
- const int timerId = ++s_threadTimerData.m_timerIdCounter;
- const system_clock::time_point deadline = system_clock::now() + timeout;
- QTimer::singleShot(timeout, context, [timerId] { handleTimeout(timerId); });
- s_threadTimerData.m_timerIdToTimerData.emplace(timerId, TimerData{deadline, context, callback});
- s_threadTimerData.m_deadlineToTimerId[deadline].append(timerId);
- return timerId;
-}
-
-TimeoutTaskAdapter::TimeoutTaskAdapter()
-{
- *task() = milliseconds::zero();
-}
-
-TimeoutTaskAdapter::~TimeoutTaskAdapter()
-{
- if (m_timerId)
- removeTimerId(*m_timerId);
-}
-
-void TimeoutTaskAdapter::start()
-{
- m_timerId = scheduleTimeout(*task(), this, [this] {
- m_timerId.reset();
- emit done(DoneResult::Success);
- });
-}
-
-ExecutableItem timeoutTask(const std::chrono::milliseconds &timeout, DoneResult result)
-{
- return TimeoutTask([timeout](std::chrono::milliseconds &t) { t = timeout; }, result);
-}
-
-/*!
- \typealias Tasking::TaskTreeTask
-
- Type alias for the CustomTask, to be used inside recipes, associated with the TaskTree task.
-*/
-
-/*!
- \typealias Tasking::TimeoutTask
-
- Type alias for the CustomTask, to be used inside recipes, associated with the
- \c std::chrono::milliseconds type. \c std::chrono::milliseconds is used to set up the
- timeout duration. The default timeout is \c std::chrono::milliseconds::zero(), that is,
- the TimeoutTask finishes as soon as the control returns to the running event loop.
-
- Example usage:
-
- \code
- using namespace std::chrono;
- using namespace std::chrono_literals;
-
- const auto onSetup = [](milliseconds &timeout) { timeout = 1000ms; }
- const auto onDone = [] { qDebug() << "Timed out."; }
-
- const Group root {
- Timeout(onSetup, onDone)
- };
- \endcode
-*/
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
diff --git a/src/assets/downloader/tasking/tasktree.h b/src/assets/downloader/tasking/tasktree.h
deleted file mode 100644
index d46bd8eee3e..00000000000
--- a/src/assets/downloader/tasking/tasktree.h
+++ /dev/null
@@ -1,757 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_TASKTREE_H
-#define TASKING_TASKTREE_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasking_global.h"
-
-#include <QtCore/QList>
-#include <QtCore/QObject>
-
-#include <memory>
-
-QT_BEGIN_NAMESPACE
-template <class T>
-class QFuture;
-
-namespace Tasking {
-
-class Do;
-class For;
-class Group;
-class GroupItem;
-using GroupItems = QList<GroupItem>;
-
-Q_NAMESPACE_EXPORT(TASKING_EXPORT)
-
-// WorkflowPolicy:
-// 1. When all children finished with success -> report success, otherwise:
-// a) Report error on first error and stop executing other children (including their subtree).
-// b) On first error - continue executing all children and report error afterwards.
-// 2. When all children finished with error -> report error, otherwise:
-// a) Report success on first success and stop executing other children (including their subtree).
-// b) On first success - continue executing all children and report success afterwards.
-// 3. Stops on first finished child. In sequential mode it will never run other children then the first one.
-// Useful only in parallel mode.
-// 4. Always run all children, let them finish, ignore their results and report success afterwards.
-// 5. Always run all children, let them finish, ignore their results and report error afterwards.
-
-enum class WorkflowPolicy
-{
- StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success).
- ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children.
- StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error).
- ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children.
- StopOnSuccessOrError, // 3 - Stops on first finished child and report its result.
- FinishAllAndSuccess, // 4 - Reports success after all children finished.
- FinishAllAndError // 5 - Reports error after all children finished.
-};
-Q_ENUM_NS(WorkflowPolicy)
-
-enum class SetupResult
-{
- Continue,
- StopWithSuccess,
- StopWithError
-};
-Q_ENUM_NS(SetupResult)
-
-enum class DoneResult
-{
- Success,
- Error
-};
-Q_ENUM_NS(DoneResult)
-
-enum class DoneWith
-{
- Success,
- Error,
- Cancel
-};
-Q_ENUM_NS(DoneWith)
-
-enum class CallDoneIf
-{
- SuccessOrError,
- Success,
- Error
-};
-Q_ENUM_NS(CallDoneIf)
-
-TASKING_EXPORT DoneResult toDoneResult(bool success);
-
-class LoopData;
-class StorageData;
-class TaskTreePrivate;
-
-class TASKING_EXPORT TaskInterface : public QObject
-{
- Q_OBJECT
-
-Q_SIGNALS:
- void done(DoneResult result);
-
-private:
- template <typename Task, typename Deleter> friend class TaskAdapter;
- friend class TaskTreePrivate;
- TaskInterface() = default;
-#ifdef Q_QDOC
-protected:
-#endif
- virtual void start() = 0;
-};
-
-class TASKING_EXPORT Loop
-{
-public:
- using Condition = std::function<bool(int)>; // Takes iteration, called prior to each iteration.
- using ValueGetter = std::function<const void *(int)>; // Takes iteration, returns ptr to ref.
-
- int iteration() const;
-
-protected:
- Loop(); // LoopForever
- Loop(int count, const ValueGetter &valueGetter = {}); // LoopRepeat, LoopList
- Loop(const Condition &condition); // LoopUntil
-
- const void *valuePtr() const;
-
-private:
- friend class ExecutionContextActivator;
- friend class TaskTreePrivate;
- std::shared_ptr<LoopData> m_loopData;
-};
-
-class TASKING_EXPORT LoopForever final : public Loop
-{
-public:
- LoopForever() : Loop() {}
-};
-
-class TASKING_EXPORT LoopRepeat final : public Loop
-{
-public:
- LoopRepeat(int count) : Loop(count) {}
-};
-
-class TASKING_EXPORT LoopUntil final : public Loop
-{
-public:
- LoopUntil(const Condition &condition) : Loop(condition) {}
-};
-
-template <typename T>
-class LoopList final : public Loop
-{
-public:
- LoopList(const QList<T> &list) : Loop(list.size(), [list](int i) { return &list.at(i); }) {}
- const T *operator->() const { return static_cast<const T *>(valuePtr()); }
- const T &operator*() const { return *static_cast<const T *>(valuePtr()); }
-};
-
-class TASKING_EXPORT StorageBase
-{
-private:
- using StorageConstructor = std::function<void *(void)>;
- using StorageDestructor = std::function<void(void *)>;
- using StorageHandler = std::function<void(void *)>;
-
- StorageBase(const StorageConstructor &ctor, const StorageDestructor &dtor);
-
- void *activeStorageVoid() const;
-
- friend bool operator==(const StorageBase &first, const StorageBase &second)
- { return first.m_storageData == second.m_storageData; }
-
- friend bool operator!=(const StorageBase &first, const StorageBase &second)
- { return first.m_storageData != second.m_storageData; }
-
- friend size_t qHash(const StorageBase &storage, uint seed = 0)
- { return size_t(storage.m_storageData.get()) ^ seed; }
-
- std::shared_ptr<StorageData> m_storageData;
-
- template <typename StorageStruct> friend class Storage;
- friend class ExecutionContextActivator;
- friend class StorageData;
- friend class RuntimeContainer;
- friend class TaskTree;
- friend class TaskTreePrivate;
-};
-
-template <typename StorageStruct>
-class Storage final : public StorageBase
-{
-public:
- Storage() : StorageBase(Storage::ctor(), Storage::dtor()) {}
-#if __cplusplus >= 201803L // C++20: Allow pack expansion in lambda init-capture.
- template <typename ...Args>
- Storage(const Args &...args)
- : StorageBase([...args = args] { return new StorageStruct(args...); }, Storage::dtor()) {}
-#else // C++17
- template <typename ...Args>
- Storage(const Args &...args)
- : StorageBase([argsTuple = std::tuple(args...)] {
- return std::apply([](const Args &...arguments) { return new StorageStruct(arguments...); }, argsTuple);
- }, Storage::dtor()) {}
-#endif
- StorageStruct &operator*() const noexcept { return *activeStorage(); }
- StorageStruct *operator->() const noexcept { return activeStorage(); }
- StorageStruct *activeStorage() const {
- return static_cast<StorageStruct *>(activeStorageVoid());
- }
-
-private:
- static StorageConstructor ctor() { return [] { return new StorageStruct(); }; }
- static StorageDestructor dtor() {
- return [](void *storage) { delete static_cast<StorageStruct *>(storage); };
- }
-};
-
-class TASKING_EXPORT GroupItem
-{
-public:
- // Called when group entered, after group's storages are created
- using GroupSetupHandler = std::function<SetupResult()>;
- // Called when group done, before group's storages are deleted
- using GroupDoneHandler = std::function<DoneResult(DoneWith)>;
-
- template <typename StorageStruct>
- GroupItem(const Storage<StorageStruct> &storage)
- : m_type(Type::Storage)
- , m_storageList{storage} {}
-
- // TODO: Add tests.
- GroupItem(const GroupItems &children) : m_type(Type::List) { addChildren(children); }
- GroupItem(std::initializer_list<GroupItem> children) : m_type(Type::List) { addChildren(children); }
-
-protected:
- GroupItem(const Loop &loop) : GroupItem(GroupData{{}, {}, {}, loop}) {}
- // Internal, provided by CustomTask
- using InterfaceCreateHandler = std::function<TaskInterface *(void)>;
- // Called prior to task start, just after createHandler
- using InterfaceSetupHandler = std::function<SetupResult(TaskInterface &)>;
- // Called on task done, just before deleteLater
- using InterfaceDoneHandler = std::function<DoneResult(const TaskInterface &, DoneWith)>;
-
- struct TaskHandler {
- InterfaceCreateHandler m_createHandler;
- InterfaceSetupHandler m_setupHandler = {};
- InterfaceDoneHandler m_doneHandler = {};
- CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError;
- };
-
- struct GroupHandler {
- GroupSetupHandler m_setupHandler;
- GroupDoneHandler m_doneHandler = {};
- CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError;
- };
-
- struct GroupData {
- GroupHandler m_groupHandler = {};
- std::optional<int> m_parallelLimit = {};
- std::optional<WorkflowPolicy> m_workflowPolicy = {};
- std::optional<Loop> m_loop = {};
- };
-
- enum class Type {
- List,
- Group,
- GroupData,
- Storage,
- TaskHandler
- };
-
- GroupItem() = default;
- GroupItem(Type type) : m_type(type) { }
- GroupItem(const GroupData &data)
- : m_type(Type::GroupData)
- , m_groupData(data) {}
- GroupItem(const TaskHandler &handler)
- : m_type(Type::TaskHandler)
- , m_taskHandler(handler) {}
- void addChildren(const GroupItems &children);
-
- static GroupItem groupHandler(const GroupHandler &handler) { return GroupItem({handler}); }
-
- // Checks if Function may be invoked with Args and if Function's return type is Result.
- template <typename Result, typename Function, typename ...Args,
- typename DecayedFunction = std::decay_t<Function>>
- static constexpr bool isInvocable()
- {
- // Note, that std::is_invocable_r_v doesn't check Result type properly.
- if constexpr (std::is_invocable_r_v<Result, DecayedFunction, Args...>)
- return std::is_same_v<Result, std::invoke_result_t<DecayedFunction, Args...>>;
- return false;
- }
-
-private:
- TASKING_EXPORT friend Group operator>>(const For &forItem, const Do &doItem);
- friend class ContainerNode;
- friend class TaskNode;
- friend class TaskTreePrivate;
- friend class ParallelLimitFunctor;
- friend class WorkflowPolicyFunctor;
- Type m_type = Type::Group;
- GroupItems m_children;
- GroupData m_groupData;
- QList<StorageBase> m_storageList;
- TaskHandler m_taskHandler;
-};
-
-class TASKING_EXPORT ExecutableItem : public GroupItem
-{
-public:
- Group withTimeout(std::chrono::milliseconds timeout,
- const std::function<void()> &handler = {}) const;
- Group withLog(const QString &logName) const;
- template <typename SenderSignalPairGetter>
- Group withCancel(SenderSignalPairGetter &&getter, std::initializer_list<GroupItem> postCancelRecipe = {}) const;
- template <typename SenderSignalPairGetter>
- Group withAccept(SenderSignalPairGetter &&getter) const;
-
-protected:
- ExecutableItem() = default;
- ExecutableItem(const TaskHandler &handler) : GroupItem(handler) {}
-
-private:
- TASKING_EXPORT friend Group operator!(const ExecutableItem &item);
- TASKING_EXPORT friend Group operator&&(const ExecutableItem &first,
- const ExecutableItem &second);
- TASKING_EXPORT friend Group operator||(const ExecutableItem &first,
- const ExecutableItem &second);
- TASKING_EXPORT friend Group operator&&(const ExecutableItem &item, DoneResult result);
- TASKING_EXPORT friend Group operator||(const ExecutableItem &item, DoneResult result);
-
- Group withCancelImpl(
- const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper,
- const GroupItems &postCancelRecipe) const;
- Group withAcceptImpl(
- const std::function<void(QObject *, const std::function<void()> &)> &connectWrapper) const;
-};
-
-class TASKING_EXPORT Group : public ExecutableItem
-{
-public:
- Group(const GroupItems &children) { addChildren(children); }
- Group(std::initializer_list<GroupItem> children) { addChildren(children); }
-
- // GroupData related:
- template <typename Handler>
- static GroupItem onGroupSetup(Handler &&handler) {
- return groupHandler({wrapGroupSetup(std::forward<Handler>(handler))});
- }
- template <typename Handler>
- static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) {
- return groupHandler({{}, wrapGroupDone(std::forward<Handler>(handler)), callDoneIf});
- }
-
-private:
- template <typename Handler>
- static GroupSetupHandler wrapGroupSetup(Handler &&handler)
- {
- // R, V stands for: Setup[R]esult, [V]oid
- static constexpr bool isR = isInvocable<SetupResult, Handler>();
- static constexpr bool isV = isInvocable<void, Handler>();
- static_assert(isR || isV,
- "Group setup handler needs to take no arguments and has to return void or SetupResult. "
- "The passed handler doesn't fulfill these requirements.");
- return [handler = std::move(handler)] {
- if constexpr (isR)
- return std::invoke(handler);
- std::invoke(handler);
- return SetupResult::Continue;
- };
- }
- template <typename Handler>
- static GroupDoneHandler wrapGroupDone(Handler &&handler)
- {
- static constexpr bool isDoneResultType = std::is_same_v<std::decay_t<Handler>, DoneResult>;
- // R, B, V, D stands for: Done[R]esult, [B]ool, [V]oid, [D]oneWith
- static constexpr bool isRD = isInvocable<DoneResult, Handler, DoneWith>();
- static constexpr bool isR = isInvocable<DoneResult, Handler>();
- static constexpr bool isBD = isInvocable<bool, Handler, DoneWith>();
- static constexpr bool isB = isInvocable<bool, Handler>();
- static constexpr bool isVD = isInvocable<void, Handler, DoneWith>();
- static constexpr bool isV = isInvocable<void, Handler>();
- static_assert(isDoneResultType || isRD || isR || isBD || isB || isVD || isV,
- "Group done handler needs to take (DoneWith) or (void) as an argument and has to "
- "return void, bool or DoneResult. Alternatively, it may be of DoneResult type. "
- "The passed handler doesn't fulfill these requirements.");
- return [handler = std::move(handler)](DoneWith result) {
- if constexpr (isDoneResultType)
- return handler;
- if constexpr (isRD)
- return std::invoke(handler, result);
- if constexpr (isR)
- return std::invoke(handler);
- if constexpr (isBD)
- return toDoneResult(std::invoke(handler, result));
- if constexpr (isB)
- return toDoneResult(std::invoke(handler));
- if constexpr (isVD)
- std::invoke(handler, result);
- else if constexpr (isV)
- std::invoke(handler);
- return toDoneResult(result == DoneWith::Success);
- };
- }
-};
-
-template <typename SenderSignalPairGetter>
-Group ExecutableItem::withCancel(SenderSignalPairGetter &&getter,
- std::initializer_list<GroupItem> postCancelRecipe) const
-{
- const auto connectWrapper = [getter](QObject *guard, const std::function<void()> &trigger) {
- const auto senderSignalPair = getter();
- QObject::connect(senderSignalPair.first, senderSignalPair.second, guard, [trigger] {
- trigger();
- }, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection));
- };
- return withCancelImpl(connectWrapper, postCancelRecipe);
-}
-
-template <typename SenderSignalPairGetter>
-Group ExecutableItem::withAccept(SenderSignalPairGetter &&getter) const
-{
- const auto connectWrapper = [getter](QObject *guard, const std::function<void()> &trigger) {
- const auto senderSignalPair = getter();
- QObject::connect(senderSignalPair.first, senderSignalPair.second, guard, [trigger] {
- trigger();
- }, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::SingleShotConnection));
- };
- return withAcceptImpl(connectWrapper);
-}
-
-template <typename Handler>
-static GroupItem onGroupSetup(Handler &&handler)
-{
- return Group::onGroupSetup(std::forward<Handler>(handler));
-}
-
-template <typename Handler>
-static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError)
-{
- return Group::onGroupDone(std::forward<Handler>(handler), callDoneIf);
-}
-
-// Default: 1 (sequential). 0 means unlimited (parallel).
-TASKING_EXPORT GroupItem parallelLimit(int limit);
-
-// Default: WorkflowPolicy::StopOnError.
-TASKING_EXPORT GroupItem workflowPolicy(WorkflowPolicy policy);
-
-TASKING_EXPORT extern const GroupItem sequential;
-TASKING_EXPORT extern const GroupItem parallel;
-TASKING_EXPORT extern const GroupItem parallelIdealThreadCountLimit;
-
-TASKING_EXPORT extern const GroupItem stopOnError;
-TASKING_EXPORT extern const GroupItem continueOnError;
-TASKING_EXPORT extern const GroupItem stopOnSuccess;
-TASKING_EXPORT extern const GroupItem continueOnSuccess;
-TASKING_EXPORT extern const GroupItem stopOnSuccessOrError;
-TASKING_EXPORT extern const GroupItem finishAllAndSuccess;
-TASKING_EXPORT extern const GroupItem finishAllAndError;
-
-TASKING_EXPORT extern const GroupItem nullItem;
-TASKING_EXPORT extern const ExecutableItem successItem;
-TASKING_EXPORT extern const ExecutableItem errorItem;
-
-class TASKING_EXPORT For final
-{
-public:
- explicit For(const Loop &loop) : m_loop(loop) {}
-
-private:
- TASKING_EXPORT friend Group operator>>(const For &forItem, const Do &doItem);
-
- Loop m_loop;
-};
-
-class When;
-
-class TASKING_EXPORT Do final
-{
-public:
- explicit Do(const GroupItems &children) : m_children(children) {}
- explicit Do(std::initializer_list<GroupItem> children) : m_children(children) {}
-
-private:
- TASKING_EXPORT friend Group operator>>(const For &forItem, const Do &doItem);
- TASKING_EXPORT friend Group operator>>(const When &whenItem, const Do &doItem);
-
- GroupItem m_children;
-};
-
-class TASKING_EXPORT Forever final : public ExecutableItem
-{
-public:
- explicit Forever(const GroupItems &children)
- { addChildren({ For (LoopForever()) >> Do { children } } ); }
- explicit Forever(std::initializer_list<GroupItem> children)
- { addChildren({ For (LoopForever()) >> Do { children } } ); }
-};
-
-// Synchronous invocation. Similarly to Group - isn't counted as a task inside taskCount()
-class TASKING_EXPORT Sync final : public ExecutableItem
-{
-public:
- template <typename Handler>
- Sync(Handler &&handler) {
- addChildren({ onGroupDone(wrapHandler(std::forward<Handler>(handler))) });
- }
-
-private:
- template <typename Handler>
- static auto wrapHandler(Handler &&handler) {
- // R, B, V stands for: Done[R]esult, [B]ool, [V]oid
- static constexpr bool isR = isInvocable<DoneResult, Handler>();
- static constexpr bool isB = isInvocable<bool, Handler>();
- static constexpr bool isV = isInvocable<void, Handler>();
- static_assert(isR || isB || isV,
- "Sync handler needs to take no arguments and has to return void, bool or DoneResult. "
- "The passed handler doesn't fulfill these requirements.");
- return handler;
- }
-};
-
-template <typename Task, typename Deleter = std::default_delete<Task>>
-class TaskAdapter : public TaskInterface
-{
-protected:
- TaskAdapter() : m_task(new Task) {}
- Task *task() { return m_task.get(); }
- const Task *task() const { return m_task.get(); }
-
-private:
- using TaskType = Task;
- using DeleterType = Deleter;
- template <typename Adapter> friend class CustomTask;
- std::unique_ptr<Task, Deleter> m_task;
-};
-
-template <typename Adapter>
-class CustomTask final : public ExecutableItem
-{
-public:
- using Task = typename Adapter::TaskType;
- using Deleter = typename Adapter::DeleterType;
- static_assert(std::is_base_of_v<TaskAdapter<Task, Deleter>, Adapter>,
- "The Adapter type for the CustomTask<Adapter> needs to be derived from "
- "TaskAdapter<Task>.");
- using TaskSetupHandler = std::function<SetupResult(Task &)>;
- using TaskDoneHandler = std::function<DoneResult(const Task &, DoneWith)>;
-
- template <typename SetupHandler = TaskSetupHandler, typename DoneHandler = TaskDoneHandler>
- CustomTask(SetupHandler &&setup = TaskSetupHandler(), DoneHandler &&done = TaskDoneHandler(),
- CallDoneIf callDoneIf = CallDoneIf::SuccessOrError)
- : ExecutableItem({&createAdapter, wrapSetup(std::forward<SetupHandler>(setup)),
- wrapDone(std::forward<DoneHandler>(done)), callDoneIf})
- {}
-
-private:
- static Adapter *createAdapter() { return new Adapter; }
-
- template <typename Handler>
- static InterfaceSetupHandler wrapSetup(Handler &&handler) {
- if constexpr (std::is_same_v<Handler, TaskSetupHandler>)
- return {}; // When user passed {} for the setup handler.
- // R, V stands for: Setup[R]esult, [V]oid
- static constexpr bool isR = isInvocable<SetupResult, Handler, Task &>();
- static constexpr bool isV = isInvocable<void, Handler, Task &>();
- static_assert(isR || isV,
- "Task setup handler needs to take (Task &) as an argument and has to return void or "
- "SetupResult. The passed handler doesn't fulfill these requirements.");
- return [handler = std::move(handler)](TaskInterface &taskInterface) {
- Adapter &adapter = static_cast<Adapter &>(taskInterface);
- if constexpr (isR)
- return std::invoke(handler, *adapter.task());
- std::invoke(handler, *adapter.task());
- return SetupResult::Continue;
- };
- }
-
- template <typename Handler>
- static InterfaceDoneHandler wrapDone(Handler &&handler) {
- if constexpr (std::is_same_v<Handler, TaskDoneHandler>)
- return {}; // User passed {} for the done handler.
- static constexpr bool isDoneResultType = std::is_same_v<std::decay_t<Handler>, DoneResult>;
- // R, B, V, T, D stands for: Done[R]esult, [B]ool, [V]oid, [T]ask, [D]oneWith
- static constexpr bool isRTD = isInvocable<DoneResult, Handler, const Task &, DoneWith>();
- static constexpr bool isRT = isInvocable<DoneResult, Handler, const Task &>();
- static constexpr bool isRD = isInvocable<DoneResult, Handler, DoneWith>();
- static constexpr bool isR = isInvocable<DoneResult, Handler>();
- static constexpr bool isBTD = isInvocable<bool, Handler, const Task &, DoneWith>();
- static constexpr bool isBT = isInvocable<bool, Handler, const Task &>();
- static constexpr bool isBD = isInvocable<bool, Handler, DoneWith>();
- static constexpr bool isB = isInvocable<bool, Handler>();
- static constexpr bool isVTD = isInvocable<void, Handler, const Task &, DoneWith>();
- static constexpr bool isVT = isInvocable<void, Handler, const Task &>();
- static constexpr bool isVD = isInvocable<void, Handler, DoneWith>();
- static constexpr bool isV = isInvocable<void, Handler>();
- static_assert(isDoneResultType || isRTD || isRT || isRD || isR
- || isBTD || isBT || isBD || isB
- || isVTD || isVT || isVD || isV,
- "Task done handler needs to take (const Task &, DoneWith), (const Task &), "
- "(DoneWith) or (void) as arguments and has to return void, bool or DoneResult. "
- "Alternatively, it may be of DoneResult type. "
- "The passed handler doesn't fulfill these requirements.");
- return [handler = std::move(handler)](const TaskInterface &taskInterface, DoneWith result) {
- if constexpr (isDoneResultType)
- return handler;
- const Adapter &adapter = static_cast<const Adapter &>(taskInterface);
- if constexpr (isRTD)
- return std::invoke(handler, *adapter.task(), result);
- if constexpr (isRT)
- return std::invoke(handler, *adapter.task());
- if constexpr (isRD)
- return std::invoke(handler, result);
- if constexpr (isR)
- return std::invoke(handler);
- if constexpr (isBTD)
- return toDoneResult(std::invoke(handler, *adapter.task(), result));
- if constexpr (isBT)
- return toDoneResult(std::invoke(handler, *adapter.task()));
- if constexpr (isBD)
- return toDoneResult(std::invoke(handler, result));
- if constexpr (isB)
- return toDoneResult(std::invoke(handler));
- if constexpr (isVTD)
- std::invoke(handler, *adapter.task(), result);
- else if constexpr (isVT)
- std::invoke(handler, *adapter.task());
- else if constexpr (isVD)
- std::invoke(handler, result);
- else if constexpr (isV)
- std::invoke(handler);
- return toDoneResult(result == DoneWith::Success);
- };
- }
-};
-
-template <typename Task>
-class SimpleTaskAdapter final : public TaskAdapter<Task>
-{
-public:
- SimpleTaskAdapter() { this->connect(this->task(), &Task::done, this, &TaskInterface::done); }
- void start() final { this->task()->start(); }
-};
-
-// A convenient helper, when:
-// 1. Task is derived from QObject.
-// 2. Task::start() method starts the task.
-// 3. Task::done(DoneResult) signal is emitted when the task is finished.
-template <typename Task>
-using SimpleCustomTask = CustomTask<SimpleTaskAdapter<Task>>;
-
-class TASKING_EXPORT TaskTree final : public QObject
-{
- Q_OBJECT
-
-public:
- TaskTree();
- TaskTree(const Group &recipe);
- ~TaskTree();
-
- void setRecipe(const Group &recipe);
-
- void start();
- void cancel();
- bool isRunning() const;
-
- // Helper methods. They execute a local event loop with ExcludeUserInputEvents.
- // The passed future is used for listening to the cancel event.
- // Don't use it in main thread. To be used in non-main threads or in auto tests.
- DoneWith runBlocking();
- DoneWith runBlocking(const QFuture<void> &future);
- static DoneWith runBlocking(const Group &recipe);
- static DoneWith runBlocking(const Group &recipe, const QFuture<void> &future);
-
- int asyncCount() const;
- int taskCount() const;
- int progressMaximum() const { return taskCount(); }
- int progressValue() const; // all finished / skipped / stopped tasks, groups itself excluded
-
- template <typename StorageStruct, typename Handler>
- void onStorageSetup(const Storage<StorageStruct> &storage, Handler &&handler) {
- static_assert(std::is_invocable_v<std::decay_t<Handler>, StorageStruct &>,
- "Storage setup handler needs to take (Storage &) as an argument. "
- "The passed handler doesn't fulfill this requirement.");
- setupStorageHandler(storage,
- wrapHandler<StorageStruct>(std::forward<Handler>(handler)), {});
- }
- template <typename StorageStruct, typename Handler>
- void onStorageDone(const Storage<StorageStruct> &storage, Handler &&handler) {
- static_assert(std::is_invocable_v<std::decay_t<Handler>, const StorageStruct &>,
- "Storage done handler needs to take (const Storage &) as an argument. "
- "The passed handler doesn't fulfill this requirement.");
- setupStorageHandler(storage, {},
- wrapHandler<const StorageStruct>(std::forward<Handler>(handler)));
- }
-
-Q_SIGNALS:
- void started();
- void done(DoneWith result);
- void asyncCountChanged(int count);
- void progressValueChanged(int value); // updated whenever task finished / skipped / stopped
-
-private:
- void setupStorageHandler(const StorageBase &storage,
- const StorageBase::StorageHandler &setupHandler,
- const StorageBase::StorageHandler &doneHandler);
- template <typename StorageStruct, typename Handler>
- StorageBase::StorageHandler wrapHandler(Handler &&handler) {
- return [handler](void *voidStruct) {
- auto *storageStruct = static_cast<StorageStruct *>(voidStruct);
- std::invoke(handler, *storageStruct);
- };
- }
-
- TaskTreePrivate *d;
-};
-
-class TASKING_EXPORT TaskTreeTaskAdapter : public TaskAdapter<TaskTree>
-{
-public:
- TaskTreeTaskAdapter();
-
-private:
- void start() final;
-};
-
-class TASKING_EXPORT TimeoutTaskAdapter : public TaskAdapter<std::chrono::milliseconds>
-{
-public:
- TimeoutTaskAdapter();
- ~TimeoutTaskAdapter();
-
-private:
- void start() final;
- std::optional<int> m_timerId;
-};
-
-using TaskTreeTask = CustomTask<TaskTreeTaskAdapter>;
-using TimeoutTask = CustomTask<TimeoutTaskAdapter>;
-
-TASKING_EXPORT ExecutableItem timeoutTask(const std::chrono::milliseconds &timeout,
- DoneResult result = DoneResult::Error);
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
-
-#endif // TASKING_TASKTREE_H
diff --git a/src/assets/downloader/tasking/tasktreerunner.cpp b/src/assets/downloader/tasking/tasktreerunner.cpp
deleted file mode 100644
index 6ed642b1bfd..00000000000
--- a/src/assets/downloader/tasking/tasktreerunner.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "tasktreerunner.h"
-
-#include "tasktree.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-TaskTreeRunner::~TaskTreeRunner() = default;
-
-void TaskTreeRunner::start(const Group &recipe,
- const SetupHandler &setupHandler,
- const DoneHandler &doneHandler)
-{
- m_taskTree.reset(new TaskTree(recipe));
- connect(m_taskTree.get(), &TaskTree::done, this, [this, doneHandler](DoneWith result) {
- m_taskTree.release()->deleteLater();
- if (doneHandler)
- doneHandler(result);
- emit done(result);
- });
- if (setupHandler)
- setupHandler(m_taskTree.get());
- emit aboutToStart(m_taskTree.get());
- m_taskTree->start();
-}
-
-void TaskTreeRunner::cancel()
-{
- if (m_taskTree)
- m_taskTree->cancel();
-}
-
-void TaskTreeRunner::reset()
-{
- m_taskTree.reset();
-}
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
diff --git a/src/assets/downloader/tasking/tasktreerunner.h b/src/assets/downloader/tasking/tasktreerunner.h
deleted file mode 100644
index f91e7608113..00000000000
--- a/src/assets/downloader/tasking/tasktreerunner.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_TASKTREERUNNER_H
-#define TASKING_TASKTREERUNNER_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasking_global.h"
-#include "tasktree.h"
-
-#include <QtCore/QObject>
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-class TASKING_EXPORT TaskTreeRunner : public QObject
-{
- Q_OBJECT
-
-public:
- using SetupHandler = std::function<void(TaskTree *)>;
- using DoneHandler = std::function<void(DoneWith)>;
-
- ~TaskTreeRunner();
-
- bool isRunning() const { return bool(m_taskTree); }
-
- // When task tree is running it resets the old task tree.
- void start(const Group &recipe,
- const SetupHandler &setupHandler = {},
- const DoneHandler &doneHandler = {});
-
- // When task tree is running it emits done(DoneWith::Cancel) synchronously.
- void cancel();
-
- // No done() signal is emitted.
- void reset();
-
-Q_SIGNALS:
- void aboutToStart(TaskTree *taskTree);
- void done(DoneWith result);
-
-private:
- std::unique_ptr<TaskTree> m_taskTree;
-};
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
-
-#endif // TASKING_TASKTREERUNNER_H
diff --git a/src/assets/downloader/tasking/tcpsocket.cpp b/src/assets/downloader/tasking/tcpsocket.cpp
deleted file mode 100644
index 19aab8fc714..00000000000
--- a/src/assets/downloader/tasking/tcpsocket.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#include "tcpsocket.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-void TcpSocket::start()
-{
- if (m_socket) {
- qWarning("The TcpSocket is already running. Ignoring the call to start().");
- return;
- }
- if (m_address.isNull()) {
- qWarning("Can't start the TcpSocket with invalid address. "
- "Stopping with an error.");
- m_error = QAbstractSocket::HostNotFoundError;
- emit done(DoneResult::Error);
- return;
- }
-
- m_socket.reset(new QTcpSocket);
- connect(m_socket.get(), &QAbstractSocket::errorOccurred, this,
- [this](QAbstractSocket::SocketError error) {
- m_error = error;
- m_socket->disconnect();
- emit done(DoneResult::Error);
- m_socket.release()->deleteLater();
- });
- connect(m_socket.get(), &QAbstractSocket::connected, this, [this] {
- if (!m_writeData.isEmpty())
- m_socket->write(m_writeData);
- emit started();
- });
- connect(m_socket.get(), &QAbstractSocket::disconnected, this, [this] {
- m_socket->disconnect();
- emit done(DoneResult::Success);
- m_socket.release()->deleteLater();
- });
-
- m_socket->connectToHost(m_address, m_port);
-}
-
-TcpSocket::~TcpSocket()
-{
- if (m_socket) {
- m_socket->disconnect();
- m_socket->abort();
- }
-}
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
diff --git a/src/assets/downloader/tasking/tcpsocket.h b/src/assets/downloader/tasking/tcpsocket.h
deleted file mode 100644
index ec0069bf130..00000000000
--- a/src/assets/downloader/tasking/tcpsocket.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (C) 2024 Jarek Kobus
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-
-#ifndef TASKING_TCPSOCKET_H
-#define TASKING_TCPSOCKET_H
-
-#include "tasking_global.h"
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "tasktree.h"
-
-#include <QtNetwork/QTcpSocket>
-
-#include <memory>
-
-QT_BEGIN_NAMESPACE
-
-namespace Tasking {
-
-// This class introduces the dependency to Qt::Network, otherwise Tasking namespace
-// is independent on Qt::Network.
-// Possibly, it could be placed inside Qt::Network library, as a wrapper around QTcpSocket.
-
-class TASKING_EXPORT TcpSocket final : public QObject
-{
- Q_OBJECT
-
-public:
- ~TcpSocket();
- void setAddress(const QHostAddress &address) { m_address = address; }
- void setPort(quint16 port) { m_port = port; }
- void setWriteData(const QByteArray &data) { m_writeData = data; }
- QTcpSocket *socket() const { return m_socket.get(); }
- void start();
-
-Q_SIGNALS:
- void started();
- void done(DoneResult result);
-
-private:
- QHostAddress m_address;
- quint16 m_port = 0;
- QByteArray m_writeData;
- std::unique_ptr<QTcpSocket> m_socket;
- QAbstractSocket::SocketError m_error = QAbstractSocket::UnknownSocketError;
-};
-
-using TcpSocketTask = SimpleCustomTask<TcpSocket>;
-
-} // namespace Tasking
-
-QT_END_NAMESPACE
-
-#endif // TASKING_TCPSOCKET_H
diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt
index 1147205b79f..c4a3480b2f9 100644
--- a/src/corelib/CMakeLists.txt
+++ b/src/corelib/CMakeLists.txt
@@ -1028,7 +1028,7 @@ qt_internal_extend_target(Core
qt_internal_extend_target(Core
CONDITION
- QT_FEATURE_timezone AND UNIX
+ QT_FEATURE_timezone AND UNIX AND NOT VXWORKS
AND NOT ANDROID AND NOT APPLE AND NOT QT_FEATURE_timezone_tzdb
SOURCES
time/qtimezoneprivate_tz.cpp
@@ -1037,7 +1037,7 @@ qt_internal_extend_target(Core
qt_internal_extend_target(Core
CONDITION
QT_FEATURE_icu AND QT_FEATURE_timezone
- AND NOT UNIX AND NOT QT_FEATURE_timezone_tzdb
+ AND (VXWORKS OR NOT UNIX) AND NOT QT_FEATURE_timezone_tzdb
SOURCES
time/qtimezoneprivate_icu.cpp
)
diff --git a/src/corelib/Qt6AndroidMacros.cmake b/src/corelib/Qt6AndroidMacros.cmake
index d7d737b36ff..6a83e947146 100644
--- a/src/corelib/Qt6AndroidMacros.cmake
+++ b/src/corelib/Qt6AndroidMacros.cmake
@@ -479,12 +479,7 @@ function(qt6_android_add_apk_target target)
endif()
# Use genex to get path to the deployment settings, the above check only to confirm that
# qt6_android_add_apk_target is called on an android executable target.
- string(JOIN "" deployment_file
- "$<GENEX_EVAL:"
- "$<TARGET_PROPERTY:${target},QT_ANDROID_DEPLOYMENT_SETTINGS_FILE>"
- ">"
- )
-
+ _qt_internal_android_get_deployment_settings_file_genex(deployment_file)
_qt_internal_android_get_deployment_tool(deployment_tool)
# No need to use genex for the BINARY_DIR since it's read-only.
@@ -527,16 +522,8 @@ function(qt6_android_add_apk_target target)
set(target_file_copy_relative_path
"libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>")
- set(extra_deps "")
-
_qt_internal_android_get_use_terminal_for_deployment(uses_terminal)
-
- # Plugins still might be added after creating the deployment targets.
- if(NOT TARGET qt_internal_plugins)
- add_custom_target(qt_internal_plugins)
- endif()
- # Before running androiddeployqt, we need to make sure all plugins are built.
- list(APPEND extra_deps qt_internal_plugins)
+ _qt_internal_android_get_common_deployment_dependencies(extra_deps)
# This target is used by Qt Creator's Android support and by the ${target}_make_apk target
# in case DEPFILEs are not supported.
@@ -726,61 +713,7 @@ function(qt6_android_add_apk_target target)
_qt_internal_android_add_global_package_dependencies(${target})
_qt_internal_create_global_apk_all_target_if_needed()
- if(QT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT)
- # When building per-ABI external projects we only need to copy ABI-specific libraries and
- # resources to the "main" ABI android build folder.
-
- if("${QT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR}" STREQUAL "")
- message(FATAL_ERROR "QT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR is not set when building"
- " ABI specific external project. This should not happen and might mean an issue"
- " in Qt. Please report a bug with CMake traces attached.")
- endif()
- # Assume that external project mirrors build structure of the top-level ABI project and
- # replace the build root when specifying the output directory of androiddeployqt.
- file(RELATIVE_PATH androiddeployqt_output_path "${CMAKE_BINARY_DIR}" "${apk_final_dir}")
- set(androiddeployqt_output_path
- "${QT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR}/${androiddeployqt_output_path}")
- _qt_internal_copy_file_if_different_command(copy_command
- "$<TARGET_FILE:${target}>"
- "${androiddeployqt_output_path}/${target_file_copy_relative_path}"
- )
- if(has_depfile_support)
- set(deploy_android_deps_dir "${apk_final_dir}/${target}_deploy_android")
- set(timestamp_file "${deploy_android_deps_dir}/timestamp")
- set(dep_file "${deploy_android_deps_dir}/${target}.d")
- add_custom_command(OUTPUT "${timestamp_file}"
- DEPENDS ${target} ${extra_deps}
- COMMAND ${CMAKE_COMMAND} -E make_directory "${deploy_android_deps_dir}"
- COMMAND ${CMAKE_COMMAND} -E touch "${timestamp_file}"
- COMMAND ${copy_command}
- COMMAND ${deployment_tool}
- --input ${deployment_file}
- --output ${androiddeployqt_output_path}
- --copy-dependencies-only
- ${extra_args}
- --depfile "${dep_file}"
- --builddir "${CMAKE_BINARY_DIR}"
- COMMENT "Resolving ${CMAKE_ANDROID_ARCH_ABI} dependencies for the ${target} APK"
- DEPFILE "${dep_file}"
- VERBATIM
- ${uses_terminal}
- )
- add_custom_target(qt_internal_${target}_copy_apk_dependencies
- DEPENDS "${timestamp_file}")
- else()
- add_custom_target(qt_internal_${target}_copy_apk_dependencies
- DEPENDS ${target} ${extra_deps}
- COMMAND ${copy_command}
- COMMAND ${deployment_tool}
- --input ${deployment_file}
- --output ${androiddeployqt_output_path}
- --copy-dependencies-only
- ${extra_args}
- COMMENT "Resolving ${CMAKE_ANDROID_ARCH_ABI} dependencies for the ${target} APK"
- ${uses_terminal}
- )
- endif()
- else()
+ if(NOT QT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT)
add_dependencies(${target}_prepare_apk_dir
${target}_copy_apk_dependencies)
endif()
@@ -790,6 +723,72 @@ function(qt6_android_add_apk_target target)
_qt_internal_collect_apk_imported_dependencies_defer("${target}")
endfunction()
+function(_qt_internal_android_copy_abi_dependencies target)
+ # When building per-ABI external projects we only need to copy ABI-specific libraries and
+ # resources to the "main" ABI android build folder.
+
+ if("${QT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR}" STREQUAL "")
+ message(FATAL_ERROR "QT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR is not set when building"
+ " ABI specific external project. This should not happen and might mean an issue"
+ " in Qt. Please report a bug with CMake traces attached.")
+ endif()
+ _qt_internal_android_get_target_deployment_dir(deployment_dir ${target})
+ # Assume that external project mirrors build structure of the top-level ABI project and
+ # replace the build root when specifying the output directory of androiddeployqt.
+ file(RELATIVE_PATH androiddeployqt_output_path "${CMAKE_BINARY_DIR}" "${deployment_dir}")
+ set(androiddeployqt_output_path
+ "${QT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR}/${androiddeployqt_output_path}")
+ set(target_file_copy_relative_path
+ "libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>")
+ _qt_internal_copy_file_if_different_command(copy_command
+ "$<TARGET_FILE:${target}>"
+ "${androiddeployqt_output_path}/${target_file_copy_relative_path}"
+ )
+
+ _qt_internal_android_get_deployment_tool(deployment_tool)
+ _qt_internal_android_get_deployment_settings_file_genex(deployment_file)
+ _qt_internal_android_get_use_terminal_for_deployment(uses_terminal)
+ _qt_internal_android_get_common_deployment_dependencies(extra_deps)
+
+ _qt_internal_check_depfile_support(has_depfile_support)
+ if(has_depfile_support)
+ set(deploy_android_deps_dir "${deployment_dir}/${target}_deploy_android")
+ set(timestamp_file "${deploy_android_deps_dir}/timestamp")
+ set(dep_file "${deploy_android_deps_dir}/${target}.d")
+ add_custom_command(OUTPUT "${timestamp_file}"
+ DEPENDS ${target} ${extra_deps}
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${deploy_android_deps_dir}"
+ COMMAND ${CMAKE_COMMAND} -E touch "${timestamp_file}"
+ COMMAND ${copy_command}
+ COMMAND ${deployment_tool}
+ --input ${deployment_file}
+ --output ${androiddeployqt_output_path}
+ --copy-dependencies-only
+ ${extra_args}
+ --depfile "${dep_file}"
+ --builddir "${CMAKE_BINARY_DIR}"
+ COMMENT "Resolving ${CMAKE_ANDROID_ARCH_ABI} dependencies for the ${target} APK"
+ DEPFILE "${dep_file}"
+ VERBATIM
+ ${uses_terminal}
+ )
+ add_custom_target(qt_internal_${target}_copy_apk_dependencies
+ DEPENDS "${timestamp_file}")
+ else()
+ add_custom_target(qt_internal_${target}_copy_apk_dependencies
+ DEPENDS ${target} ${extra_deps}
+ COMMAND ${copy_command}
+ COMMAND ${deployment_tool}
+ --input ${deployment_file}
+ --output ${androiddeployqt_output_path}
+ --copy-dependencies-only
+ ${extra_args}
+ COMMENT "Resolving ${CMAKE_ANDROID_ARCH_ABI} dependencies for the ${target} APK"
+ ${uses_terminal}
+ )
+ endif()
+endfunction()
+
function(_qt_internal_create_global_android_targets)
macro(_qt_internal_create_global_android_targets_impl target)
string(TOUPPER "${target}" target_upper)
@@ -1587,6 +1586,8 @@ function(_qt_internal_configure_android_multiabi_target target)
"-DCMAKE_TOOLCHAIN_FILE=${qt_abi_toolchain_path}"
"-DQT_HOST_PATH=${QT_HOST_PATH}"
"-DQT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT=ON"
+ "-DQT_USE_ANDROID_MODERN_BUNDLE=${QT_USE_ANDROID_MODERN_BUNDLE}"
+ "-DQT_USE_ANDROID_TARGET_BUILD_DIR=${QT_USE_ANDROID_TARGET_BUILD_DIR}"
"-DQT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR=${CMAKE_BINARY_DIR}"
"${config_arg}"
"${extra_cmake_args}"
@@ -1686,6 +1687,9 @@ function(_qt_internal_android_executable_finalizer target)
else()
qt6_android_add_apk_target("${target}")
endif()
+ if(QT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT)
+ _qt_internal_android_copy_abi_dependencies("${target}")
+ endif()
_qt_internal_android_create_runner_wrapper("${target}")
set_property(TARGET ${target} PROPERTY _qt_android_in_finalizer "")
endfunction()
@@ -1817,21 +1821,12 @@ function(_qt_internal_expose_android_package_source_dir_to_ide target)
endfunction()
function(_qt_internal_android_add_aux_deployment target)
- cmake_parse_arguments(arg "" "OUTPUT_TARGET_NAME;DEPLOYMENT_DIRECTORY" "EXTRA_ARGS" ${ARGN})
+ cmake_parse_arguments(arg "" "OUTPUT_TARGET_NAME" "EXTRA_ARGS" ${ARGN})
_qt_internal_validate_all_args_are_parsed(arg)
- string(JOIN "" deployment_file
- "$<GENEX_EVAL:"
- "$<TARGET_PROPERTY:${target},QT_ANDROID_DEPLOYMENT_SETTINGS_FILE>"
- ">"
- )
-
+ _qt_internal_android_get_deployment_settings_file_genex(deployment_file)
_qt_internal_android_get_deployment_tool(deployment_tool)
- if(arg_DEPLOYMENT_DIRECTORY)
- set(deployment_dir "${arg_DEPLOYMENT_DIRECTORY}")
- else()
- _qt_internal_android_get_target_deployment_dir(deployment_dir ${target})
- endif()
+ _qt_internal_android_get_target_deployment_dir(deployment_dir ${target})
cmake_policy(PUSH)
if(POLICY CMP0116)
@@ -1867,7 +1862,7 @@ function(_qt_internal_android_add_aux_deployment target)
${arg_EXTRA_ARGS}
#TODO: Support signing
COMMENT "Deploying Android artifacts for ${target}"
- DEPENDS "${target}" "${deployment_file}"
+ DEPENDS "${target}" "${deployment_file}" ${target}_copy_apk_dependencies
VERBATIM
${uses_terminal}
)
@@ -2045,5 +2040,27 @@ function(_qt_internal_android_find_asan_wrap_sh out_wrap_sh_path)
endif()
endfunction()
+# Returns path to the android deployment settings
+function(_qt_internal_android_get_deployment_settings_file_genex out_var)
+ string(JOIN "" deployment_file
+ "$<GENEX_EVAL:"
+ "$<TARGET_PROPERTY:${target},QT_ANDROID_DEPLOYMENT_SETTINGS_FILE>"
+ ">"
+ )
+
+ set(${out_var} "${deployment_file}" PARENT_SCOPE)
+endfunction()
+
+function(_qt_internal_android_get_common_deployment_dependencies out_var)
+ # Plugins still might be added after creating the deployment targets.
+ if(NOT TARGET qt_internal_plugins)
+ add_custom_target(qt_internal_plugins)
+ endif()
+ # Before running androiddeployqt, we need to make sure all plugins are built.
+ list(APPEND extra_deps qt_internal_plugins)
+
+ set(${out_var} "${extra_deps}" PARENT_SCOPE)
+endfunction()
+
set(QT_INTERNAL_ANDROID_TARGET_BUILD_DIR_SUPPORT ON CACHE INTERNAL
"Indicates that Qt supports per-target Android build directories")
diff --git a/src/corelib/compat/removed_api.cpp b/src/corelib/compat/removed_api.cpp
index 6303a455491..b7ef3ee06f1 100644
--- a/src/corelib/compat/removed_api.cpp
+++ b/src/corelib/compat/removed_api.cpp
@@ -1290,6 +1290,13 @@ QByteArray QMetaEnum::valueToKeys(int value) const
#include "qmutex.h"
+#include "qbytearray.h"
+
+QByteArray QByteArray::percentDecoded(char percent) const
+{
+ return fromPercentEncoding(*this, percent);
+}
+
#if QT_CONFIG(thread)
void QBasicMutex::destroyInternal(QMutexPrivate *d)
{
diff --git a/src/corelib/configure.cmake b/src/corelib/configure.cmake
index d951b85c147..edcfba0f6ce 100644
--- a/src/corelib/configure.cmake
+++ b/src/corelib/configure.cmake
@@ -1150,7 +1150,7 @@ qt_feature("timezone" PUBLIC
SECTION "Utilities"
LABEL "QTimeZone"
PURPOSE "Provides support for time-zone handling."
- CONDITION NOT WASM AND NOT VXWORKS
+ CONDITION NOT WASM
)
qt_feature("timezone_locale" PRIVATE
SECTION "Utilities"
diff --git a/src/corelib/doc/images/javaiterators1.svg b/src/corelib/doc/images/javaiterators1.svg
new file mode 100644
index 00000000000..468dbe5371c
--- /dev/null
+++ b/src/corelib/doc/images/javaiterators1.svg
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ width="340"
+ height="110"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+
+<style>
+ svg .box-style { stroke: black; fill: white }
+ svg .line-style { stroke: red; fill: none }
+ svg .text-style { font: 20px arial; fill: black }
+ svg .fill-style { stroke: none; fill: red }
+
+ [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black }
+ [data-theme="dark"] svg .line-style { stroke: red; fill: none }
+ [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 }
+ [data-theme="dark"] svg .fill-style { stroke: none; fill: red }
+
+ [data-theme="light"] svg .box-style { stroke: black; fill: white }
+ [data-theme="light"] svg .line-style { stroke: red; fill: none }
+ [data-theme="light"] svg .text-style { font: 20px arial; fill: black }
+ [data-theme="light"] svg .fill-style { stroke: none; fill: red }
+</style>
+
+<g transform="translate(10.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">A</text>
+<path d="M 0,60 v 30" class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+</g>
+
+<g transform="translate(90.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">B</text>
+<path d="M 0,60 v 30" class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+</g>
+
+<g transform="translate(170.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">C</text>
+<path d="M 0,60 v 30" class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+</g>
+
+<g transform="translate(250.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">D</text>
+<path d="M 0,60 v 30" class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+</g>
+
+<g transform="translate(330.5, 10.5)">
+<path d="M 0,60 v 30" class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+</g>
+
+</svg>
diff --git a/src/corelib/doc/images/javaiterators2.svg b/src/corelib/doc/images/javaiterators2.svg
new file mode 100644
index 00000000000..df4c6b352a6
--- /dev/null
+++ b/src/corelib/doc/images/javaiterators2.svg
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ version="1.1"
+ width="340"
+ height="130"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+
+<style>
+ svg .box-style { stroke: black; fill: white }
+ svg .line-style { stroke: red; fill: none }
+ svg .fill-style { stroke: none; fill: red }
+ svg .np-line-style { stroke: blue; fill: none }
+ svg .np-fill-style { stroke: none; fill: blue }
+ svg .text-style { font: 20px arial; fill: black }
+ svg .small-text-style { font: 12px monospace; fill: black }
+
+ [data-theme="dark"] svg .box-style { stroke: #f2f2f2; fill: black }
+ [data-theme="dark"] svg .line-style { stroke: red; fill: none }
+ [data-theme="dark"] svg .fill-style { stroke: none; fill: red }
+ [data-theme="dark"] svg .np-line-style { stroke: #4080ff; fill: none; stroke-width: 1.5 }
+ [data-theme="dark"] svg .np-fill-style { stroke: none; fill: #4080ff }
+ [data-theme="dark"] svg .text-style { font: 20px arial; fill: #f2f2f2 }
+ [data-theme="dark"] svg .small-text-style { font: 12px monospace; fill: #f2f2f2 }
+
+ [data-theme="light"] svg .box-style { stroke: black; fill: white }
+ [data-theme="light"] svg .line-style { stroke: red; fill: none }
+ [data-theme="light"] svg .fill-style { stroke: none; fill: red }
+ [data-theme="light"] svg .np-line-style { stroke: blue; fill: none }
+ [data-theme="light"] svg .np-fill-style { stroke: none; fill: blue }
+ [data-theme="light"] svg .text-style { font: 20px arial; fill: black }
+ [data-theme="light"] svg .small-text-style { font: 12px monospace; fill: black }
+</style>
+
+<g transform="translate(10.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">A</text>
+</g>
+
+<g transform="translate(90.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">B</text>
+<path d="M 0,60 c 0,30 50,40 80,30" class="np-line-style" />
+<path d="M 0,60 l -2,14 l 11,-4 z" class="np-fill-style" />
+<text x="-15" y="110" class="small-text-style">previous()</text>
+</g>
+
+<g transform="translate(170.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">C</text>
+<path d="M 0,60 v 50" class="line-style" />
+<path d="M 0,60 l -5,10 l 10,0 z" class="fill-style" />
+<text x="30" y="110" class="small-text-style">next()</text>
+</g>
+
+<g transform="translate(250.5, 10.5)">
+<path d="m 0,0 h 80 v 60 h -80 z" class="box-style" />
+<text x="35" y="36" class="text-style">D</text>
+<path d="M 0,60 c 0,30 -50,40 -80,30" class="np-line-style" />
+<path d="M 0,60 l 2,14 l -11,-4 z" class="np-fill-style" />
+</g>
+
+</svg>
diff --git a/src/corelib/doc/src/java-style-iterators.qdoc b/src/corelib/doc/src/java-style-iterators.qdoc
index 856005cb66c..a0e5c53d633 100644
--- a/src/corelib/doc/src/java-style-iterators.qdoc
+++ b/src/corelib/doc/src/java-style-iterators.qdoc
@@ -42,7 +42,7 @@
diagram below shows the valid iterator positions as red arrows for a list
containing four items:
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
Here's a typical loop for iterating through all the elements of a
QList<QString> in order:
@@ -70,7 +70,7 @@
\l{QListIterator::next()}{next()} and
\l{QListIterator::previous()}{previous()} on an iterator:
- \image javaiterators2.png
+ \image javaiterators2.png Iterating to the next and previous items
The following table summarizes the QListIterator API:
diff --git a/src/corelib/doc/src/objectmodel/bindableproperties.qdoc b/src/corelib/doc/src/objectmodel/bindableproperties.qdoc
index 9b3ea6ae660..5dc2e6dad12 100644
--- a/src/corelib/doc/src/objectmodel/bindableproperties.qdoc
+++ b/src/corelib/doc/src/objectmodel/bindableproperties.qdoc
@@ -172,7 +172,7 @@
The following illustrates this approach.
- \badcode
+ \code
void DerivedClass::setValue(int val)
{
// do something
@@ -247,7 +247,7 @@
be called for the current value of the property, register your callback using
subscribe() instead.
- \section1 Interaction with Q_PROPERTYs
+ \section1 Interaction with Q_PROPERTY
A \l {The Property System}{Q_PROPERTY} that defines \c BINDABLE can be bound and
used in binding expressions. You can implement such properties using \l {QProperty},
diff --git a/src/corelib/global/qassert.cpp b/src/corelib/global/qassert.cpp
index e4f3a76e4f4..2741077977c 100644
--- a/src/corelib/global/qassert.cpp
+++ b/src/corelib/global/qassert.cpp
@@ -204,7 +204,20 @@ void qBadAlloc()
Do not use it in new code. It is retained as-is for compatibility with old
code and will likely be removed in the next major version Qt.
- \sa Q_ASSERT(), Q_UNREACHABLE(), Q_LIKELY()
+ \sa Q_ASSERT(), Q_UNREACHABLE(), Q_LIKELY(), Q_PRESUME()
+*/
+
+/*!
+ \macro void Q_PRESUME(bool expr)
+ \relates <QtAssert>
+ \since 6.11
+
+ Causes the compiler to assume that \a expr is \c true.
+
+ This macro emits Q_ASSERT() and a C++23-style \c{[[assume]]} attribute
+ when supported by the compiler. Otherwise it falls back to Q_ASSERT().
+
+ \sa Q_ASSERT(), Q_UNREACHABLE(), Q_LIKELY(), Q_ASSUME()
*/
/*!
@@ -240,7 +253,7 @@ void qBadAlloc()
compilers that need them, without causing warnings for compilers that
complain about its presence.
- \sa Q_ASSERT(), qFatal(), Q_UNREACHABLE_RETURN()
+ \sa Q_ASSERT(), qFatal(), Q_UNREACHABLE_RETURN(), Q_PRESUME()
*/
/*!
@@ -255,6 +268,6 @@ void qBadAlloc()
\endcode
except it omits the return on compilers that would warn about it.
- \sa Q_UNREACHABLE()
+ \sa Q_UNREACHABLE(), Q_PRESUME()
*/
QT_END_NAMESPACE
diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h
index 19c938f8c3c..0ed6bb7e0a9 100644
--- a/src/corelib/io/qfile.h
+++ b/src/corelib/io/qfile.h
@@ -10,17 +10,6 @@
#include <QtCore/qstring.h>
#include <stdio.h>
-#if QT_CONFIG(cxx17_filesystem)
-#include <filesystem>
-#elif defined(Q_QDOC)
-namespace std {
- namespace filesystem {
- class path {
- };
- };
-};
-#endif
-
#ifdef open
#error qfile.h must be included before any header file that defines open
#endif
@@ -57,26 +46,10 @@ public:
#if QT_CONFIG(cxx17_filesystem)
namespace QtPrivate {
-inline QString fromFilesystemPath(const std::filesystem::path &path)
-{
- // we could use QAnyStringView, but this allows us to statically determine
- // the correct toString() call
- using View = std::conditional_t<sizeof(std::filesystem::path::value_type) == sizeof(char16_t),
- QStringView, QUtf8StringView>;
- return View(path.native()).toString();
-}
-
-inline std::filesystem::path toFilesystemPath(const QString &path)
-{
- if constexpr (sizeof(std::filesystem::path::value_type) == sizeof(char16_t))
- return std::u16string_view(QStringView(path));
- else
- return path.toStdString();
-}
-
// Both std::filesystem::path and QString (without QT_NO_CAST_FROM_ASCII) can be implicitly
// constructed from string literals so we force the std::fs::path parameter to only
// accept std::fs::path with no implicit conversions.
+// ### Qt7: use Q_WEAK_OVERLOAD
template<typename T>
using ForceFilesystemPath = typename std::enable_if_t<std::is_same_v<std::filesystem::path, T>, int>;
}
diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h
index 18ecd035122..4d51fa50d7e 100644
--- a/src/corelib/io/qfiledevice.h
+++ b/src/corelib/io/qfiledevice.h
@@ -8,11 +8,43 @@
#include <QtCore/qiodevice.h>
#include <QtCore/qstring.h>
+#if QT_CONFIG(cxx17_filesystem)
+#include <filesystem>
+#elif defined(Q_QDOC)
+namespace std {
+ namespace filesystem {
+ class path {
+ };
+ };
+};
+#endif
+
QT_BEGIN_NAMESPACE
class QDateTime;
class QFileDevicePrivate;
+#if QT_CONFIG(cxx17_filesystem)
+namespace QtPrivate {
+inline QString fromFilesystemPath(const std::filesystem::path &path)
+{
+ // we could use QAnyStringView, but this allows us to statically determine
+ // the correct toString() call
+ using View = std::conditional_t<sizeof(std::filesystem::path::value_type) == sizeof(char16_t),
+ QStringView, QUtf8StringView>;
+ return View(path.native()).toString();
+}
+
+inline std::filesystem::path toFilesystemPath(const QString &path)
+{
+ if constexpr (sizeof(std::filesystem::path::value_type) == sizeof(char16_t))
+ return std::u16string_view(QStringView(path));
+ else
+ return path.toStdString();
+}
+} // namespace QtPrivate
+#endif // QT_CONFIG(cxx17_filesystem)
+
#if !defined(QT_USE_NODISCARD_FILE_OPEN) && !defined(QT_NO_USE_NODISCARD_FILE_OPEN)
# if QT_VERSION < QT_VERSION_CHECK(6, 10, 0)
# define QT_NO_USE_NODISCARD_FILE_OPEN
diff --git a/src/corelib/io/qiooperation_p_p.h b/src/corelib/io/qiooperation_p_p.h
index d6fef439a85..470e0858fd3 100644
--- a/src/corelib/io/qiooperation_p_p.h
+++ b/src/corelib/io/qiooperation_p_p.h
@@ -73,34 +73,34 @@ public:
ReadSpans &getReadSpans()
{
Q_ASSERT(containsReadSpans());
- return std::get<ReadSpans>(data);
+ return *std::get_if<ReadSpans>(&data);
}
const ReadSpans &getReadSpans() const
{
Q_ASSERT(containsReadSpans());
- return std::get<ReadSpans>(data);
+ return *std::get_if<ReadSpans>(&data);
}
WriteSpans &getWriteSpans()
{
Q_ASSERT(containsWriteSpans());
- return std::get<WriteSpans>(data);
+ return *std::get_if<WriteSpans>(&data);
}
const WriteSpans &getWriteSpans() const
{
Q_ASSERT(containsWriteSpans());
- return std::get<WriteSpans>(data);
+ return *std::get_if<WriteSpans>(&data);
}
QByteArray &getByteArray()
{
Q_ASSERT(containsByteArray());
- return std::get<QByteArray>(data);
+ return *std::get_if<QByteArray>(&data);
}
const QByteArray &getByteArray() const
{
Q_ASSERT(containsByteArray());
- return std::get<QByteArray>(data);
+ return *std::get_if<QByteArray>(&data);
}
// Potentially can be extended to return a QVariant::value<T>().
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp
index 47229c8e6a1..4d431b46213 100644
--- a/src/corelib/io/qlockfile.cpp
+++ b/src/corelib/io/qlockfile.cpp
@@ -379,8 +379,9 @@ QLockFilePrivate::~QLockFilePrivate()
QByteArray QLockFilePrivate::lockFileContents() const
{
// Use operator% from the fast builder to avoid multiple memory allocations.
- return QByteArray::number(QCoreApplication::applicationPid()) % '\n'
- % processNameByPid(QCoreApplication::applicationPid()).toUtf8() % '\n'
+ qint64 pid = QCoreApplication::applicationPid();
+ return QByteArray::number(pid) % '\n'
+ % processNameByPid(pid).toUtf8() % '\n'
% machineName().toUtf8() % '\n'
% QSysInfo::machineUniqueId() % '\n'
% QSysInfo::bootUniqueId() % '\n';
@@ -415,8 +416,8 @@ bool QLockFilePrivate::getLockInfo_helper(const QString &fileName, LockFileInfo
bool ok;
info->appname = QString::fromUtf8(appNameLine);
info->hostname = QString::fromUtf8(hostNameLine);
- info->hostid = hostId;
- info->bootid = bootId;
+ info->hostid = std::move(hostId);
+ info->bootid = std::move(bootId);
info->pid = pidLine.toLongLong(&ok);
return ok && info->pid > 0;
}
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index e6204ffc6ce..0422244d9ba 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -92,6 +92,14 @@ QSaveFile::QSaveFile(const QString &name, QObject *parent)
}
/*!
+ \fn QSaveFile::QSaveFile(const std::filesystem::path &path, QObject *parent)
+ \since 6.11
+
+ Constructs a new file object with the given \a parent to represent the
+ file with the specified \a path.
+*/
+
+/*!
Destroys the file object, discarding the saved contents unless commit() was called.
*/
QSaveFile::~QSaveFile()
@@ -116,6 +124,12 @@ QString QSaveFile::fileName() const
}
/*!
+ \fn std::filesystem::path QSaveFile::filesystemFileName() const
+ \since 6.11
+ Returns fileName() as \c{std::filesystem::path}.
+*/
+
+/*!
Sets the \a name of the file. The name can have no path, a
relative path, or an absolute path.
@@ -127,6 +141,12 @@ void QSaveFile::setFileName(const QString &name)
}
/*!
+ \fn QSaveFile::setFileName(const std::filesystem::path &name)
+ \since 6.11
+ \overload
+*/
+
+/*!
Opens the file using \a mode flags. Returns \c true if successful;
otherwise returns \c false.
diff --git a/src/corelib/io/qsavefile.h b/src/corelib/io/qsavefile.h
index 1738969ffa1..910ae8c8d5f 100644
--- a/src/corelib/io/qsavefile.h
+++ b/src/corelib/io/qsavefile.h
@@ -45,6 +45,20 @@ public:
void setDirectWriteFallback(bool enabled);
bool directWriteFallback() const;
+#if QT_CONFIG(cxx17_filesystem) || defined(Q_QDOC)
+ Q_WEAK_OVERLOAD QSaveFile(const std::filesystem::path &path, QObject *parent = nullptr)
+ : QSaveFile(QtPrivate::fromFilesystemPath(path), parent)
+ {
+ }
+
+ std::filesystem::path filesystemFileName() const
+ { return QtPrivate::toFilesystemPath(fileName()); }
+ Q_WEAK_OVERLOAD void setFileName(const std::filesystem::path &name)
+ {
+ setFileName(QtPrivate::fromFilesystemPath(name));
+ }
+#endif // QT_CONFIG(cxx17_filesystem)
+
protected:
qint64 writeData(const char *data, qint64 len) override;
diff --git a/src/corelib/itemmodels/qrangemodel.cpp b/src/corelib/itemmodels/qrangemodel.cpp
index b594f1de22a..b0c6c46b125 100644
--- a/src/corelib/itemmodels/qrangemodel.cpp
+++ b/src/corelib/itemmodels/qrangemodel.cpp
@@ -20,6 +20,8 @@ public:
private:
std::unique_ptr<QRangeModelImplBase, QRangeModelImplBase::Deleter> impl;
+ friend class QRangeModelImplBase;
+
mutable QHash<int, QByteArray> m_roleNames;
};
@@ -28,6 +30,16 @@ QRangeModel::QRangeModel(QRangeModelImplBase *impl, QObject *parent)
{
}
+QRangeModelImplBase *QRangeModelImplBase::getImplementation(QRangeModel *model)
+{
+ return model->d_func()->impl.get();
+}
+
+const QRangeModelImplBase *QRangeModelImplBase::getImplementation(const QRangeModel *model)
+{
+ return model->d_func()->impl.get();
+}
+
/*!
\class QRangeModel
\inmodule QtCore
@@ -303,7 +315,7 @@ QRangeModel::QRangeModel(QRangeModelImplBase *impl, QObject *parent)
tree data structure needs to be homomorphic: on all levels of the tree, the
list of child rows needs to use the exact same representation as the tree
itself. In addition, the row type needs be of a static size: either a gadget
- or QObject type, or a type that implements the {C++ tuple protocol}.
+ or QObject type, or a type that implements \l{the C++ tuple protocol}.
To represent such data as a tree, QRangeModel has to be able to traverse the
data structure: for any given row, the model needs to be able to retrieve
diff --git a/src/corelib/itemmodels/qrangemodel_impl.h b/src/corelib/itemmodels/qrangemodel_impl.h
index f38dc88c0d9..c2f473542d7 100644
--- a/src/corelib/itemmodels/qrangemodel_impl.h
+++ b/src/corelib/itemmodels/qrangemodel_impl.h
@@ -842,6 +842,11 @@ namespace QRangeModelDetails
{
using protocol = wrapped_t<Protocol>;
using row = typename range_traits<wrapped_t<Range>>::value_type;
+ static constexpr bool is_tree = std::conjunction_v<protocol_parentRow<protocol, row>,
+ protocol_childRows<protocol, row>>;
+ static constexpr bool is_list = static_size_v<row> == 0
+ && (!has_metaobject_v<row> || row_category<row>::isMultiRole);
+ static constexpr bool is_table = !is_list && !is_tree;
static constexpr bool has_newRow = protocol_newRow<protocol>();
static constexpr bool has_deleteRow = protocol_deleteRow<protocol, row>();
@@ -1046,6 +1051,9 @@ public:
typename C::MultiData
>;
+ static Q_CORE_EXPORT QRangeModelImplBase *getImplementation(QRangeModel *model);
+ static Q_CORE_EXPORT const QRangeModelImplBase *getImplementation(const QRangeModel *model);
+
private:
friend class QRangeModelPrivate;
QRangeModel *m_rangeModel;
@@ -1147,13 +1155,6 @@ protected:
}
}
- static constexpr bool isMutable()
- {
- return range_features::is_mutable && row_features::is_mutable
- && std::is_reference_v<row_reference>
- && Structure::is_mutable_impl;
- }
-
static constexpr int static_row_count = QRangeModelDetails::static_size_v<range_type>;
static constexpr bool rows_are_raw_pointers = std::is_pointer_v<row_type>;
static constexpr bool rows_are_owning_or_raw_pointers =
@@ -1161,9 +1162,6 @@ protected:
static constexpr int static_column_count = QRangeModelDetails::static_size_v<row_type>;
static constexpr bool one_dimensional_range = static_column_count == 0;
- static constexpr bool dynamicRows() { return isMutable() && static_row_count < 0; }
- static constexpr bool dynamicColumns() { return static_column_count < 0; }
-
// A row might be a value (or range of values), or a pointer.
// row_ptr is always a pointer, and const_row_ptr is a pointer to const.
using row_ptr = wrapped_row_type *;
@@ -1205,6 +1203,15 @@ protected:
"The range holding a move-only row-type must support insert(pos, start, end)");
public:
+ static constexpr bool isMutable()
+ {
+ return range_features::is_mutable && row_features::is_mutable
+ && std::is_reference_v<row_reference>
+ && Structure::is_mutable_impl;
+ }
+ static constexpr bool dynamicRows() { return isMutable() && static_row_count < 0; }
+ static constexpr bool dynamicColumns() { return static_column_count < 0; }
+
explicit QRangeModelImpl(Range &&model, Protocol&& protocol, QRangeModel *itemModel)
: Ancestor(itemModel)
, ProtocolStorage{std::forward<Protocol>(protocol)}
@@ -1236,7 +1243,7 @@ public:
if (row == index.row() && column == index.column())
return index;
- if (column < 0 || column >= this->itemModel().columnCount())
+ if (column < 0 || column >= this->columnCount({}))
return {};
if (row == index.row())
@@ -1974,8 +1981,8 @@ public:
}
if (sourceRow == destRow || sourceRow == destRow - 1 || count <= 0
- || sourceRow < 0 || sourceRow + count - 1 >= this->itemModel().rowCount(sourceParent)
- || destRow < 0 || destRow > this->itemModel().rowCount(destParent)) {
+ || sourceRow < 0 || sourceRow + count - 1 >= this->rowCount(sourceParent)
+ || destRow < 0 || destRow > this->rowCount(destParent)) {
return false;
}
@@ -1995,11 +2002,14 @@ public:
}
}
- QModelIndex parent(const QModelIndex &child) const { return that().parent(child); }
+ const protocol_type& protocol() const { return QRangeModelDetails::refTo(ProtocolStorage::object()); }
+ protocol_type& protocol() { return QRangeModelDetails::refTo(ProtocolStorage::object()); }
+
+ QModelIndex parent(const QModelIndex &child) const { return that().parentImpl(child); }
- int rowCount(const QModelIndex &parent) const { return that().rowCount(parent); }
+ int rowCount(const QModelIndex &parent) const { return that().rowCountImpl(parent); }
- int columnCount(const QModelIndex &parent) const { return that().columnCount(parent); }
+ int columnCount(const QModelIndex &parent) const { return that().columnCountImpl(parent); }
void destroy() { delete std::addressof(that()); }
@@ -2035,6 +2045,11 @@ public:
protected:
~QRangeModelImpl()
{
+ deleteOwnedRows();
+ }
+
+ void deleteOwnedRows()
+ {
// We delete row objects if we are not operating on a reference or pointer
// to a range, as in that case, the owner of the referenced/pointed to
// range also owns the row entries.
@@ -2335,9 +2350,6 @@ protected:
}
- const protocol_type& protocol() const { return QRangeModelDetails::refTo(ProtocolStorage::object()); }
- protocol_type& protocol() { return QRangeModelDetails::refTo(ProtocolStorage::object()); }
-
ModelData m_data;
};
@@ -2385,7 +2397,7 @@ protected:
return this->createIndex(row, column, QRangeModelDetails::pointerTo(*it));
}
- QModelIndex parent(const QModelIndex &child) const
+ QModelIndex parentImpl(const QModelIndex &child) const
{
if (!child.isValid())
return {};
@@ -2410,12 +2422,12 @@ protected:
return {};
}
- int rowCount(const QModelIndex &parent) const
+ int rowCountImpl(const QModelIndex &parent) const
{
return Base::size(this->childRange(parent));
}
- int columnCount(const QModelIndex &) const
+ int columnCountImpl(const QModelIndex &) const
{
// all levels of a tree have to have the same, static, column count
if constexpr (Base::one_dimensional_range)
@@ -2662,6 +2674,9 @@ class QGenericTableItemModelImpl
using Base = QRangeModelImpl<QGenericTableItemModelImpl<Range>, Range>;
friend class QRangeModelImpl<QGenericTableItemModelImpl<Range>, Range>;
+ static constexpr bool is_mutable_impl = true;
+
+public:
using range_type = typename Base::range_type;
using range_features = typename Base::range_features;
using row_type = typename Base::row_type;
@@ -2669,9 +2684,6 @@ class QGenericTableItemModelImpl
using row_traits = typename Base::row_traits;
using row_features = typename Base::row_features;
- static constexpr bool is_mutable_impl = true;
-
-public:
explicit QGenericTableItemModelImpl(Range &&model, QRangeModel *itemModel)
: Base(std::forward<Range>(model), {}, itemModel)
{}
@@ -2692,19 +2704,19 @@ protected:
}
}
- QModelIndex parent(const QModelIndex &) const
+ QModelIndex parentImpl(const QModelIndex &) const
{
return {};
}
- int rowCount(const QModelIndex &parent) const
+ int rowCountImpl(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
return int(Base::size(*this->m_data.model()));
}
- int columnCount(const QModelIndex &parent) const
+ int columnCountImpl(const QModelIndex &parent) const
{
if (parent.isValid())
return 0;
@@ -2760,7 +2772,7 @@ protected:
// dynamically sized rows all have to have the same column count
if constexpr (Base::dynamicColumns() && row_features::has_resize) {
if (QRangeModelDetails::isValid(empty_row))
- QRangeModelDetails::refTo(empty_row).resize(this->itemModel().columnCount());
+ QRangeModelDetails::refTo(empty_row).resize(this->columnCount({}));
}
return empty_row;
diff --git a/src/corelib/kernel/qassociativeiterable.cpp b/src/corelib/kernel/qassociativeiterable.cpp
index 625fa0a869e..8e3072169dd 100644
--- a/src/corelib/kernel/qassociativeiterable.cpp
+++ b/src/corelib/kernel/qassociativeiterable.cpp
@@ -8,6 +8,11 @@
QT_BEGIN_NAMESPACE
/*!
+ \class QAssociativeIterator
+ \internal
+ */
+
+/*!
Returns the key this iterator points to.
*/
QVariant QAssociativeIterator::key() const
@@ -49,6 +54,11 @@ QVariantPointer<QAssociativeIterator> QAssociativeIterator::operator->() const
}
/*!
+ \class QAssociativeConstIterator
+ \internal
+ */
+
+/*!
Returns the key this iterator points to.
*/
QVariant QAssociativeConstIterator::key() const
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 0c7e7db3188..de7c4df6d1d 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2512,7 +2512,7 @@ QString QCoreApplication::applicationFilePath()
Returns the current process ID for the application.
*/
-qint64 QCoreApplication::applicationPid()
+qint64 QCoreApplication::applicationPid() noexcept
{
#if defined(Q_OS_WIN)
return GetCurrentProcessId();
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 55c8097adc5..054e53a4a41 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -119,7 +119,7 @@ public:
static QString applicationDirPath();
static QString applicationFilePath();
- Q_DECL_CONST_FUNCTION static qint64 applicationPid();
+ Q_DECL_CONST_FUNCTION static qint64 applicationPid() noexcept;
#if QT_CONFIG(permissions) || defined(Q_QDOC)
Qt::PermissionStatus checkPermission(const QPermission &permission);
diff --git a/src/corelib/kernel/qpermissions.cpp b/src/corelib/kernel/qpermissions.cpp
index 8c95431d01f..bbcea8338ca 100644
--- a/src/corelib/kernel/qpermissions.cpp
+++ b/src/corelib/kernel/qpermissions.cpp
@@ -132,6 +132,10 @@ Q_LOGGING_CATEGORY(lcPermissions, "qt.permissions", QtWarningMsg);
\annotatedlist permissions
+ \note The available permission types cover core functionality of Qt modules
+ like Qt Multimedia and Qt Positioning, but do not encompass all platform-specific
+ permissions. Custom permission types are not currently supported.
+
\section1 Best Practices
To ensure the best possible user experience for the end user we recommend
diff --git a/src/corelib/kernel/qsequentialiterable.cpp b/src/corelib/kernel/qsequentialiterable.cpp
index 94a2e501cd7..32c58266045 100644
--- a/src/corelib/kernel/qsequentialiterable.cpp
+++ b/src/corelib/kernel/qsequentialiterable.cpp
@@ -178,6 +178,11 @@ void QSequentialIterable::set(qsizetype idx, const QVariant &value)
*/
/*!
+ \class QSequentialIterator
+ \internal
+ */
+
+/*!
Returns the current item, converted to a QVariantRef.
*/
QVariantRef<QSequentialIterator> QSequentialIterator::operator*() const
@@ -194,6 +199,11 @@ QVariantPointer<QSequentialIterator> QSequentialIterator::operator->() const
}
/*!
+ \class QSequentialConstIterator
+ \internal
+ */
+
+/*!
Returns the current item, converted to a QVariant.
*/
QVariant QSequentialConstIterator::operator*() const
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index 06dc614c352..93f905afc48 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -158,7 +158,7 @@ void QMimeDatabasePrivate::loadProviders()
const QMimeDatabasePrivate::Providers &QMimeDatabasePrivate::providers()
{
-#ifndef Q_OS_WASM // stub implementation always returns true
+#if QT_CONFIG(thread) // stub implementation always returns true
Q_ASSERT(!mutex.tryLock()); // caller should have locked mutex
#endif
if (m_providers.empty()) {
@@ -289,7 +289,9 @@ QStringList QMimeDatabasePrivate::mimeParents(const QString &mimeName)
QStringList QMimeDatabasePrivate::parents(const QString &mimeName)
{
+#if QT_CONFIG(thread) // stub implementation always returns true
Q_ASSERT(!mutex.tryLock());
+#endif
QStringList result;
for (const auto &provider : providers())
provider->addParents(mimeName, result);
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 4ccc58b3f39..de7043e8c1d 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -377,7 +377,6 @@ void QMimeBinaryProvider::findByMagic(const QByteArray &data, QMimeMagicResult &
void QMimeBinaryProvider::addParents(const QString &mime, QStringList &result)
{
- const QByteArray mimeStr = mime.toLatin1();
const int parentListOffset = m_cacheFile->getUint32(PosParentListOffset);
const int numEntries = m_cacheFile->getUint32(parentListOffset);
@@ -388,7 +387,7 @@ void QMimeBinaryProvider::addParents(const QString &mime, QStringList &result)
const int off = parentListOffset + 4 + 8 * medium;
const int mimeOffset = m_cacheFile->getUint32(off);
const char *aMime = m_cacheFile->getCharStar(mimeOffset);
- const int cmp = qstrcmp(aMime, mimeStr);
+ const int cmp = QLatin1StringView(aMime).compare(mime);
if (cmp < 0) {
begin = medium + 1;
} else if (cmp > 0) {
@@ -409,7 +408,6 @@ void QMimeBinaryProvider::addParents(const QString &mime, QStringList &result)
QString QMimeBinaryProvider::resolveAlias(const QString &name)
{
- const QByteArray input = name.toLatin1();
const int aliasListOffset = m_cacheFile->getUint32(PosAliasListOffset);
const int numEntries = m_cacheFile->getUint32(aliasListOffset);
int begin = 0;
@@ -419,7 +417,7 @@ QString QMimeBinaryProvider::resolveAlias(const QString &name)
const int off = aliasListOffset + 4 + 8 * medium;
const int aliasOffset = m_cacheFile->getUint32(off);
const char *alias = m_cacheFile->getCharStar(aliasOffset);
- const int cmp = qstrcmp(alias, input);
+ const int cmp = QLatin1StringView(alias).compare(name);
if (cmp < 0) {
begin = medium + 1;
} else if (cmp > 0) {
@@ -435,7 +433,6 @@ QString QMimeBinaryProvider::resolveAlias(const QString &name)
void QMimeBinaryProvider::addAliases(const QString &name, QStringList &result)
{
- const QByteArray input = name.toLatin1();
const int aliasListOffset = m_cacheFile->getUint32(PosAliasListOffset);
const int numEntries = m_cacheFile->getUint32(aliasListOffset);
for (int pos = 0; pos < numEntries; ++pos) {
@@ -443,7 +440,7 @@ void QMimeBinaryProvider::addAliases(const QString &name, QStringList &result)
const int mimeOffset = m_cacheFile->getUint32(off + 4);
const char *mimeType = m_cacheFile->getCharStar(mimeOffset);
- if (input == mimeType) {
+ if (name == QLatin1StringView(mimeType)) {
const int aliasOffset = m_cacheFile->getUint32(off);
const char *alias = m_cacheFile->getCharStar(aliasOffset);
const QString strAlias = QString::fromLatin1(alias);
@@ -586,7 +583,7 @@ QMimeBinaryProvider::loadMimeTypeExtra(const QString &mimeName)
// Binary search in the icons or generic-icons list
QLatin1StringView QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int posListOffset,
- const QByteArray &inputMime)
+ QStringView inputMime)
{
const int iconsListOffset = cacheFile->getUint32(posListOffset);
const int numIcons = cacheFile->getUint32(iconsListOffset);
@@ -597,7 +594,7 @@ QLatin1StringView QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int pos
const int off = iconsListOffset + 4 + 8 * medium;
const int mimeOffset = cacheFile->getUint32(off);
const char *mime = cacheFile->getCharStar(mimeOffset);
- const int cmp = qstrcmp(mime, inputMime);
+ const int cmp = QLatin1StringView(mime).compare(inputMime);
if (cmp < 0)
begin = medium + 1;
else if (cmp > 0)
@@ -612,14 +609,12 @@ QLatin1StringView QMimeBinaryProvider::iconForMime(CacheFile *cacheFile, int pos
QString QMimeBinaryProvider::icon(const QString &name)
{
- const QByteArray inputMime = name.toLatin1();
- return iconForMime(m_cacheFile.get(), PosIconsListOffset, inputMime);
+ return iconForMime(m_cacheFile.get(), PosIconsListOffset, name);
}
QString QMimeBinaryProvider::genericIcon(const QString &name)
{
- const QByteArray inputMime = name.toLatin1();
- return iconForMime(m_cacheFile.get(), PosGenericIconsListOffset, inputMime);
+ return iconForMime(m_cacheFile.get(), PosGenericIconsListOffset, name);
}
////
diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h
index aede727d710..d597651b362 100644
--- a/src/corelib/mimetypes/qmimeprovider_p.h
+++ b/src/corelib/mimetypes/qmimeprovider_p.h
@@ -111,7 +111,7 @@ private:
bool caseSensitiveCheck);
bool matchMagicRule(CacheFile *cacheFile, int numMatchlets, int firstOffset,
const QByteArray &data);
- QLatin1StringView iconForMime(CacheFile *cacheFile, int posListOffset, const QByteArray &inputMime);
+ QLatin1StringView iconForMime(CacheFile *cacheFile, int posListOffset, QStringView inputMime);
void loadMimeTypeList();
bool checkCacheChanged();
diff --git a/src/corelib/platform/wasm/qstdweb.cpp b/src/corelib/platform/wasm/qstdweb.cpp
index d1fff5388c6..287138bb915 100644
--- a/src/corelib/platform/wasm/qstdweb.cpp
+++ b/src/corelib/platform/wasm/qstdweb.cpp
@@ -177,15 +177,13 @@ Blob Blob::slice(uint32_t begin, uint32_t end) const
ArrayBuffer Blob::arrayBuffer_sync() const
{
- QEventLoop loop;
emscripten::val buffer;
- qstdweb::Promise::make(m_blob, QStringLiteral("arrayBuffer"), {
- .thenFunc = [&loop, &buffer](emscripten::val arrayBuffer) {
+ uint32_t handlerIndex = qstdweb::Promise::make(m_blob, QStringLiteral("arrayBuffer"), {
+ .thenFunc = [&buffer](emscripten::val arrayBuffer) {
buffer = arrayBuffer;
- loop.quit();
}
});
- loop.exec();
+ Promise::suspendExclusive(handlerIndex);
return ArrayBuffer(buffer);
}
@@ -443,7 +441,7 @@ EventCallback::EventCallback(emscripten::val element, const std::string &name,
}
-void Promise::adoptPromise(emscripten::val promise, PromiseCallbacks callbacks)
+uint32_t Promise::adoptPromise(emscripten::val promise, PromiseCallbacks callbacks)
{
Q_ASSERT_X(!!callbacks.catchFunc || !!callbacks.finallyFunc || !!callbacks.thenFunc,
"Promise::adoptPromise", "must provide at least one callback function");
@@ -499,13 +497,23 @@ void Promise::adoptPromise(emscripten::val promise, PromiseCallbacks callbacks)
promise = promise.call<emscripten::val>("finally",
suspendResume->jsEventHandlerAt(*finallyIndex));
+
+ return *finallyIndex;
+}
+
+void Promise::suspendExclusive(uint32_t handlerIndex)
+{
+ QWasmSuspendResumeControl *suspendResume = QWasmSuspendResumeControl::get();
+ Q_ASSERT(suspendResume);
+ suspendResume->suspendExclusive(handlerIndex);
+ suspendResume->sendPendingEvents();
}
void Promise::all(std::vector<emscripten::val> promises, PromiseCallbacks callbacks)
{
auto arr = emscripten::val::array(promises);
auto all = val::global("Promise").call<emscripten::val>("all", arr);
- return adoptPromise(all, callbacks);
+ adoptPromise(all, callbacks);
}
// Asyncify and thread blocking: Normally, it's not possible to block the main
@@ -630,6 +638,249 @@ qint64 Uint8ArrayIODevice::writeData(const char *data, qint64 maxSize)
return size;
}
+FileSystemWritableFileStreamIODevice::FileSystemWritableFileStreamIODevice(FileSystemWritableFileStream stream)
+ : m_stream(std::move(stream))
+{
+}
+
+bool FileSystemWritableFileStreamIODevice::open(QIODevice::OpenMode mode)
+{
+ if (mode.testFlag(QIODevice::ReadOnly))
+ return false;
+ return QIODevice::open(mode);
+}
+
+void FileSystemWritableFileStreamIODevice::close()
+{
+ if (!isOpen()) {
+ QIODevice::close();
+ return;
+ }
+
+ uint32_t handlerIndex = Promise::make(m_stream.val(), QStringLiteral("close"), {
+ .thenFunc = [](emscripten::val) {
+ }
+ });
+ Promise::suspendExclusive(handlerIndex);
+
+ QIODevice::close();
+}
+
+bool FileSystemWritableFileStreamIODevice::isSequential() const
+{
+ return false;
+}
+
+qint64 FileSystemWritableFileStreamIODevice::size() const
+{
+ return m_size;
+}
+
+bool FileSystemWritableFileStreamIODevice::seek(qint64 pos)
+{
+ bool success = false;
+
+ emscripten::val seekParams = emscripten::val::object();
+ seekParams.set("type", std::string("seek"));
+ seekParams.set("position", static_cast<double>(pos));
+ uint32_t handlerIndex = Promise::make(m_stream.val(), QStringLiteral("write"), {
+ .thenFunc = [&success](emscripten::val) {
+ success = true;
+ },
+ .catchFunc = [](emscripten::val) {
+ }
+ }, seekParams);
+ Promise::suspendExclusive(handlerIndex);
+
+ if (!success)
+ return false;
+
+ return QIODevice::seek(pos);
+}
+
+qint64 FileSystemWritableFileStreamIODevice::readData(char *, qint64)
+{
+ Q_UNREACHABLE();
+}
+
+qint64 FileSystemWritableFileStreamIODevice::writeData(const char *data, qint64 size)
+{
+ bool success = false;
+
+ Uint8Array array = Uint8Array::copyFrom(data, size);
+ uint32_t handlerIndex = Promise::make(m_stream.val(), QStringLiteral("write"), {
+ .thenFunc = [&success](emscripten::val) {
+ success = true;
+ },
+ .catchFunc = [](emscripten::val) {
+ }
+ }, array.val());
+ Promise::suspendExclusive(handlerIndex);
+
+ if (success) {
+ qint64 newPos = pos() + size;
+ m_size = std::max(m_size, newPos);
+ return size;
+ }
+ return -1;
+}
+
+FileSystemWritableFileStream::FileSystemWritableFileStream(const emscripten::val &writableStream)
+ : m_writableStream(writableStream)
+{
+}
+
+emscripten::val FileSystemWritableFileStream::val() const
+{
+ return m_writableStream;
+}
+
+FileSystemFileHandle::FileSystemFileHandle(const emscripten::val &fileHandle)
+ : m_fileHandle(fileHandle)
+{
+}
+
+std::string FileSystemFileHandle::name() const
+{
+ return m_fileHandle["name"].as<std::string>();
+}
+
+std::string FileSystemFileHandle::kind() const
+{
+ return m_fileHandle["kind"].as<std::string>();
+}
+
+emscripten::val FileSystemFileHandle::val() const
+{
+ return m_fileHandle;
+}
+
+FileSystemFileIODevice::FileSystemFileIODevice(FileSystemFileHandle fileHandle)
+ : m_fileHandle(fileHandle)
+{
+}
+
+bool FileSystemFileIODevice::open(QIODevice::OpenMode mode)
+{
+ if (isOpen())
+ return false;
+
+ // Read mode: get the File and create a BlobIODevice
+ if (mode & QIODevice::ReadOnly) {
+ File file;
+ bool success = false;
+
+ uint32_t handlerIndex = Promise::make(m_fileHandle.val(), QStringLiteral("getFile"), {
+ .thenFunc = [&file, &success](emscripten::val fileVal) {
+ file = File(fileVal);
+ success = true;
+ },
+ .catchFunc = [](emscripten::val) {
+ }
+ });
+ Promise::suspendExclusive(handlerIndex);
+
+ if (success) {
+ m_blobDevice = std::make_unique<BlobIODevice>(file.slice(0, file.size()));
+ m_size = file.size();
+
+ if (!m_blobDevice->open(mode))
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ // Write mode: create a writable stream
+ if (mode & QIODevice::WriteOnly) {
+ FileSystemWritableFileStream writableStream;
+ bool success = false;
+
+ uint32_t handlerIndex = Promise::make(m_fileHandle.val(), QStringLiteral("createWritable"), {
+ .thenFunc = [&writableStream, &success](emscripten::val writable) {
+ writableStream = FileSystemWritableFileStream(writable);
+ success = true;
+ },
+ .catchFunc = [](emscripten::val) {
+ }
+ });
+ Promise::suspendExclusive(handlerIndex);
+
+ if (success) {
+ m_writableDevice = std::make_unique<FileSystemWritableFileStreamIODevice>(writableStream);
+ if (!m_writableDevice->open(mode))
+ return false;
+ } else {
+ return false;
+ }
+ }
+
+ return QIODevice::open(mode);
+}
+
+void FileSystemFileIODevice::close()
+{
+ if (!isOpen()) {
+ QIODevice::close();
+ return;
+ }
+
+ if (m_writableDevice) {
+ m_writableDevice->close();
+ m_writableDevice.reset();
+ }
+ if (m_blobDevice) {
+ m_blobDevice->close();
+ m_blobDevice.reset();
+ }
+
+ QIODevice::close();
+}
+
+bool FileSystemFileIODevice::isSequential() const
+{
+ return false;
+}
+
+qint64 FileSystemFileIODevice::size() const
+{
+ return m_size;
+}
+
+bool FileSystemFileIODevice::seek(qint64 pos)
+{
+ if (m_blobDevice) {
+ if (!m_blobDevice->seek(pos))
+ return false;
+ }
+ if (m_writableDevice) {
+ if (!m_writableDevice->seek(pos))
+ return false;
+ }
+ return QIODevice::seek(pos);
+}
+
+qint64 FileSystemFileIODevice::readData(char *data, qint64 maxSize)
+{
+ if (!m_blobDevice)
+ return -1;
+
+ return m_blobDevice->read(data, maxSize);
+}
+
+qint64 FileSystemFileIODevice::writeData(const char *data, qint64 size)
+{
+ if (!m_writableDevice)
+ return -1;
+
+ qint64 written = m_writableDevice->write(data, size);
+ if (written > 0) {
+ qint64 newPos = pos() + written;
+ m_size = std::max(m_size, newPos);
+ }
+ return written;
+}
+
} // namespace qstdweb
QT_END_NAMESPACE
diff --git a/src/corelib/platform/wasm/qstdweb_p.h b/src/corelib/platform/wasm/qstdweb_p.h
index 711751f65ab..9a97370448e 100644
--- a/src/corelib/platform/wasm/qstdweb_p.h
+++ b/src/corelib/platform/wasm/qstdweb_p.h
@@ -195,6 +195,30 @@ namespace qstdweb {
emscripten::val m_uint8Array = emscripten::val::undefined();
};
+ class Q_CORE_EXPORT FileSystemWritableFileStream {
+ public:
+ FileSystemWritableFileStream() = default;
+ explicit FileSystemWritableFileStream(const emscripten::val &writableStream);
+ emscripten::val val() const;
+
+ private:
+ emscripten::val m_writableStream = emscripten::val::undefined();
+ };
+
+ class Q_CORE_EXPORT FileSystemFileHandle {
+ public:
+ FileSystemFileHandle() = default;
+ explicit FileSystemFileHandle(const emscripten::val &fileHandle);
+
+ std::string name() const;
+ std::string kind() const;
+
+ emscripten::val val() const;
+
+ private:
+ emscripten::val m_fileHandle = emscripten::val::undefined();
+ };
+
// EventCallback here for source compatibility; prefer using QWasmEventHandler directly
class Q_CORE_EXPORT EventCallback : public QWasmEventHandler
{
@@ -214,13 +238,13 @@ namespace qstdweb {
};
namespace Promise {
- void Q_CORE_EXPORT adoptPromise(emscripten::val promise, PromiseCallbacks callbacks);
+ uint32_t Q_CORE_EXPORT adoptPromise(emscripten::val promise, PromiseCallbacks callbacks);
template<typename... Args>
- void make(emscripten::val target,
- QString methodName,
- PromiseCallbacks callbacks,
- Args... args)
+ uint32_t make(emscripten::val target,
+ QString methodName,
+ PromiseCallbacks callbacks,
+ Args... args)
{
emscripten::val promiseObject = target.call<emscripten::val>(
methodName.toStdString().c_str(), std::forward<Args>(args)...);
@@ -228,9 +252,10 @@ namespace qstdweb {
qFatal("This function did not return a promise");
}
- adoptPromise(std::move(promiseObject), std::move(callbacks));
+ return adoptPromise(std::move(promiseObject), std::move(callbacks));
}
+ void Q_CORE_EXPORT suspendExclusive(uint32_t handlerIndex);
void Q_CORE_EXPORT all(std::vector<emscripten::val> promises, PromiseCallbacks callbacks);
};
@@ -274,6 +299,46 @@ namespace qstdweb {
Uint8Array m_array;
};
+ class Q_CORE_EXPORT FileSystemWritableFileStreamIODevice: public QIODevice
+ {
+ public:
+ FileSystemWritableFileStreamIODevice(FileSystemWritableFileStream stream);
+ bool open(QIODevice::OpenMode mode) override;
+ void close() override;
+ bool isSequential() const override;
+ qint64 size() const override;
+ bool seek(qint64 pos) override;
+
+ protected:
+ qint64 readData(char *data, qint64 maxSize) override;
+ qint64 writeData(const char *data, qint64 size) override;
+
+ private:
+ FileSystemWritableFileStream m_stream;
+ qint64 m_size = 0;
+ };
+
+ class Q_CORE_EXPORT FileSystemFileIODevice: public QIODevice
+ {
+ public:
+ FileSystemFileIODevice(FileSystemFileHandle fileHandle);
+ bool open(QIODevice::OpenMode mode) override;
+ void close() override;
+ bool isSequential() const override;
+ qint64 size() const override;
+ bool seek(qint64 pos) override;
+
+ protected:
+ qint64 readData(char *data, qint64 maxSize) override;
+ qint64 writeData(const char *data, qint64 size) override;
+
+ private:
+ FileSystemFileHandle m_fileHandle;
+ std::unique_ptr<BlobIODevice> m_blobDevice;
+ std::unique_ptr<FileSystemWritableFileStreamIODevice> m_writableDevice;
+ qint64 m_size = 0;
+ };
+
inline emscripten::val window()
{
static emscripten::val savedWindow = emscripten::val::global("window");
diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp
index 961bbb53e54..093898c520a 100644
--- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp
+++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol.cpp
@@ -49,6 +49,7 @@ void qtSuspendResumeControlClearJs() {
asyncifyEnabled: false, // asyncify 1 or JSPI enabled
eventHandlers: {},
pendingEvents: [],
+ exclusiveEventHandler: 0,
});
});
}
@@ -118,7 +119,15 @@ void qtRegisterEventHandlerJs(int index) {
});
// Handle the event based on instance state and asyncify flag
- if (control.resume) {
+ if (control.exclusiveEventHandler > 0) {
+ // In exclusive mode, resume on exclusive event handler match only
+ if (index != control.exclusiveEventHandler)
+ return;
+
+ const resume = control.resume;
+ control.resume = null;
+ resume();
+ } else if (control.resume) {
// The instance is suspended in processEvents(), resume and process the event
const resume = control.resume;
control.resume = null;
@@ -148,14 +157,12 @@ QWasmSuspendResumeControl::QWasmSuspendResumeControl()
#endif
qtSuspendResumeControlClearJs();
suspendResumeControlJs().set("asyncifyEnabled", qstdweb::haveAsyncify());
- Q_ASSERT(!QWasmSuspendResumeControl::s_suspendResumeControl);
QWasmSuspendResumeControl::s_suspendResumeControl = this;
}
QWasmSuspendResumeControl::~QWasmSuspendResumeControl()
{
qtSuspendResumeControlClearJs();
- Q_ASSERT(QWasmSuspendResumeControl::s_suspendResumeControl);
QWasmSuspendResumeControl::s_suspendResumeControl = nullptr;
}
@@ -199,13 +206,24 @@ void QWasmSuspendResumeControl::suspend()
qtSuspendJs();
}
-// Sends any pending events. Returns true if an event was sent, false otherwise.
+void QWasmSuspendResumeControl::suspendExclusive(uint32_t eventHandlerIndex)
+{
+ suspendResumeControlJs().set("exclusiveEventHandler", eventHandlerIndex);
+ qtSuspendJs();
+}
+
+// Sends any pending events. Returns the number of sent events.
int QWasmSuspendResumeControl::sendPendingEvents()
{
#if QT_CONFIG(thread)
Q_ASSERT(emscripten_is_main_runtime_thread());
#endif
- emscripten::val pendingEvents = suspendResumeControlJs()["pendingEvents"];
+ emscripten::val control = suspendResumeControlJs();
+ emscripten::val pendingEvents = control["pendingEvents"];
+
+ if (control["exclusiveEventHandler"].as<int>() > 0)
+ return sendPendingExclusiveEvent();
+
if (pendingEvents["length"].as<int>() == 0)
return 0;
@@ -214,13 +232,28 @@ int QWasmSuspendResumeControl::sendPendingEvents()
// Grab one event (handler and arg), and call it
emscripten::val event = pendingEvents.call<val>("shift");
auto it = m_eventHandlers.find(event["index"].as<int>());
- Q_ASSERT(it != m_eventHandlers.end());
- it->second(event["arg"]);
+ if (it != m_eventHandlers.end())
+ it->second(event["arg"]);
++count;
}
return count;
}
+// Sends the pending exclusive event, and resets the "exclusive" state
+int QWasmSuspendResumeControl::sendPendingExclusiveEvent()
+{
+ emscripten::val control = suspendResumeControlJs();
+ int exclusiveHandlerIndex = control["exclusiveEventHandler"].as<int>();
+ control.set("exclusiveEventHandler", 0);
+ emscripten::val event = control["pendingEvents"].call<val>("pop");
+ int eventHandlerIndex = event["index"].as<int>();
+ Q_ASSERT(exclusiveHandlerIndex == eventHandlerIndex);
+ auto it = m_eventHandlers.find(eventHandlerIndex);
+ Q_ASSERT(it != m_eventHandlers.end());
+ it->second(event["arg"]);
+ return 1;
+}
+
void qtSendPendingEvents()
{
if (QWasmSuspendResumeControl::s_suspendResumeControl)
diff --git a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h
index 2b9962e4be1..37c71ed8123 100644
--- a/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h
+++ b/src/corelib/platform/wasm/qwasmsuspendresumecontrol_p.h
@@ -38,7 +38,9 @@ public:
static emscripten::val suspendResumeControlJs();
void suspend();
+ void suspendExclusive(uint32_t eventHandlerIndex);
int sendPendingEvents();
+ int sendPendingExclusiveEvent();
private:
friend void qtSendPendingEvents();
diff --git a/src/corelib/plugin/qlibrary.h b/src/corelib/plugin/qlibrary.h
index f31047b214a..95c14178b22 100644
--- a/src/corelib/plugin/qlibrary.h
+++ b/src/corelib/plugin/qlibrary.h
@@ -63,6 +63,7 @@ private:
Loaded
};
+ friend class QLibraryPrivate;
QTaggedPointer<QLibraryPrivate, LoadStatusTag> d = nullptr;
Q_DISABLE_COPY(QLibrary)
};
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index b4e29a79e28..2331c86d844 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -67,7 +67,7 @@ public:
bool load();
QtPluginInstanceFunction loadPlugin(); // loads and resolves instance
- bool unload(UnloadFlag flag = UnloadSys);
+ Q_AUTOTEST_EXPORT bool unload(UnloadFlag flag = UnloadSys);
void release();
QFunctionPointer resolve(const char *);
@@ -103,6 +103,11 @@ public:
void updatePluginState();
bool isPlugin();
+ static QLibraryPrivate* get(QLibrary* lib)
+ {
+ return lib->d.data();
+ }
+
private:
explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints);
~QLibraryPrivate();
diff --git a/src/corelib/serialization/qdatastream.cpp b/src/corelib/serialization/qdatastream.cpp
index 7d04a19a5fa..ae3bed5b751 100644
--- a/src/corelib/serialization/qdatastream.cpp
+++ b/src/corelib/serialization/qdatastream.cpp
@@ -508,50 +508,50 @@ void QDataStream::setByteOrder(ByteOrder bo)
This enum provides symbolic synonyms for the data serialization
format version numbers.
- \value Qt_1_0 Version 1 (Qt 1.x)
- \value Qt_2_0 Version 2 (Qt 2.0)
- \value Qt_2_1 Version 3 (Qt 2.1, 2.2, 2.3)
- \value Qt_3_0 Version 4 (Qt 3.0)
- \value Qt_3_1 Version 5 (Qt 3.1, 3.2)
- \value Qt_3_3 Version 6 (Qt 3.3)
- \value Qt_4_0 Version 7 (Qt 4.0, Qt 4.1)
- \value Qt_4_1 Version 7 (Qt 4.0, Qt 4.1)
- \value Qt_4_2 Version 8 (Qt 4.2)
- \value Qt_4_3 Version 9 (Qt 4.3)
- \value Qt_4_4 Version 10 (Qt 4.4)
- \value Qt_4_5 Version 11 (Qt 4.5)
- \value Qt_4_6 Version 12 (Qt 4.6, Qt 4.7, Qt 4.8)
- \value Qt_4_7 Same as Qt_4_6.
- \value Qt_4_8 Same as Qt_4_6.
- \value Qt_4_9 Same as Qt_4_6.
- \value Qt_5_0 Version 13 (Qt 5.0)
- \value Qt_5_1 Version 14 (Qt 5.1)
- \value Qt_5_2 Version 15 (Qt 5.2)
- \value Qt_5_3 Same as Qt_5_2
- \value Qt_5_4 Version 16 (Qt 5.4)
- \value Qt_5_5 Same as Qt_5_4
- \value Qt_5_6 Version 17 (Qt 5.6)
- \value Qt_5_7 Same as Qt_5_6
- \value Qt_5_8 Same as Qt_5_6
- \value Qt_5_9 Same as Qt_5_6
- \value Qt_5_10 Same as Qt_5_6
- \value Qt_5_11 Same as Qt_5_6
- \value Qt_5_12 Version 18 (Qt 5.12)
- \value Qt_5_13 Version 19 (Qt 5.13)
- \value Qt_5_14 Same as Qt_5_13
- \value Qt_5_15 Same as Qt_5_13
- \value Qt_6_0 Version 20 (Qt 6.0)
- \value Qt_6_1 Same as Qt_6_0
- \value Qt_6_2 Same as Qt_6_0
- \value Qt_6_3 Same as Qt_6_0
- \value Qt_6_4 Same as Qt_6_0
- \value Qt_6_5 Same as Qt_6_0
- \value Qt_6_6 Version 21 (Qt 6.6)
- \value Qt_6_7 Version 22 (Qt 6.7)
- \value Qt_6_8 Same as Qt_6_7
- \value Qt_6_9 Same as Qt_6_7
- \value Qt_6_10 Same as Qt_6_7
- \value Qt_6_11 Same as Qt_6_10
+ \value Qt_1_0
+ \value Qt_2_0
+ \value Qt_2_1
+ \value Qt_3_0
+ \value Qt_3_1
+ \value Qt_3_3
+ \value Qt_4_0
+ \value Qt_4_1
+ \value Qt_4_2
+ \value Qt_4_3
+ \value Qt_4_4
+ \value Qt_4_5
+ \value Qt_4_6
+ \value Qt_4_7
+ \value Qt_4_8
+ \value Qt_4_9
+ \value Qt_5_0
+ \value Qt_5_1
+ \value Qt_5_2
+ \value Qt_5_3
+ \value Qt_5_4
+ \value Qt_5_5
+ \value Qt_5_6
+ \value Qt_5_7
+ \value Qt_5_8
+ \value Qt_5_9
+ \value Qt_5_10
+ \value Qt_5_11
+ \value Qt_5_12
+ \value Qt_5_13
+ \value Qt_5_14
+ \value Qt_5_15
+ \value Qt_6_0
+ \value Qt_6_1
+ \value Qt_6_2
+ \value Qt_6_3
+ \value Qt_6_4
+ \value Qt_6_5
+ \value Qt_6_6
+ \value Qt_6_7
+ \value Qt_6_8
+ \value Qt_6_9
+ \value Qt_6_10
+ \value Qt_6_11
\omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
diff --git a/src/corelib/text/qbytearray.cpp b/src/corelib/text/qbytearray.cpp
index 54f2bb8f145..ead4ea490f9 100644
--- a/src/corelib/text/qbytearray.cpp
+++ b/src/corelib/text/qbytearray.cpp
@@ -4725,47 +4725,32 @@ QByteArray QByteArray::toHex(char separator) const
return hex;
}
-static void q_fromPercentEncoding(QByteArray *ba, char percent)
+static qsizetype q_fromPercentEncoding(QByteArrayView src, char percent, QSpan<char> buffer)
{
- if (ba->isEmpty())
- return;
-
- char *data = ba->data();
- const char *inputPtr = data;
+ char *data = buffer.begin();
+ const char *inputPtr = src.begin();
qsizetype i = 0;
- qsizetype len = ba->size();
- qsizetype outlen = 0;
- int a, b;
- char c;
+ const qsizetype len = src.size();
while (i < len) {
- c = inputPtr[i];
+ char c = inputPtr[i];
if (c == percent && i + 2 < len) {
- a = inputPtr[++i];
- b = inputPtr[++i];
-
- if (a >= '0' && a <= '9') a -= '0';
- else if (a >= 'a' && a <= 'f') a = a - 'a' + 10;
- else if (a >= 'A' && a <= 'F') a = a - 'A' + 10;
-
- if (b >= '0' && b <= '9') b -= '0';
- else if (b >= 'a' && b <= 'f') b = b - 'a' + 10;
- else if (b >= 'A' && b <= 'F') b = b - 'A' + 10;
-
- *data++ = (char)((a << 4) | b);
+ if (int a = QtMiscUtils::fromHex(uchar(inputPtr[++i])); a != -1)
+ *data = a << 4;
+ if (int b = QtMiscUtils::fromHex(uchar(inputPtr[++i])); b != -1)
+ *data |= b;
} else {
- *data++ = c;
+ *data = c;
}
-
+ ++data;
++i;
- ++outlen;
}
- if (outlen != len)
- ba->truncate(outlen);
+ return data - buffer.begin();
}
/*!
+ \fn QByteArray QByteArray::percentDecoded(char percent) const &
\since 6.4
Decodes URI/URL-style percent-encoding.
@@ -4783,15 +4768,12 @@ static void q_fromPercentEncoding(QByteArray *ba, char percent)
\sa toPercentEncoding(), QUrl::fromPercentEncoding()
*/
-QByteArray QByteArray::percentDecoded(char percent) const
-{
- if (isEmpty())
- return *this; // Preserves isNull().
- QByteArray tmp = *this;
- q_fromPercentEncoding(&tmp, percent);
- return tmp;
-}
+/*!
+ \fn QByteArray QByteArray::percentDecoded(char percent) &&
+ \since 6.11
+ \overload
+*/
/*!
\since 4.4
@@ -4809,7 +4791,30 @@ QByteArray QByteArray::percentDecoded(char percent) const
*/
QByteArray QByteArray::fromPercentEncoding(const QByteArray &input, char percent)
{
- return input.percentDecoded(percent);
+ if (input.isEmpty())
+ return input; // Preserves isNull().
+
+ QByteArray out{input.size(), Qt::Uninitialized};
+ qsizetype len = q_fromPercentEncoding(input, percent, out);
+ out.truncate(len);
+ return out;
+}
+
+/*!
+ \overload
+ \since 6.11
+*/
+QByteArray QByteArray::fromPercentEncoding(QByteArray &&input, char percent)
+{
+ if (input.d->needsDetach())
+ return fromPercentEncoding(input, percent); // lvalue overload
+
+ if (input.isEmpty())
+ return std::move(input); // Preserves isNull().
+
+ qsizetype len = q_fromPercentEncoding(input, percent, input);
+ input.truncate(len);
+ return std::move(input);
}
/*! \fn QByteArray QByteArray::fromStdString(const std::string &str)
diff --git a/src/corelib/text/qbytearray.h b/src/corelib/text/qbytearray.h
index 9fb832545f8..7dd85437472 100644
--- a/src/corelib/text/qbytearray.h
+++ b/src/corelib/text/qbytearray.h
@@ -400,7 +400,14 @@ public:
QByteArray toPercentEncoding(const QByteArray &exclude = QByteArray(),
const QByteArray &include = QByteArray(),
char percent = '%') const;
+#if QT_CORE_REMOVED_SINCE(6, 11)
[[nodiscard]] QByteArray percentDecoded(char percent = '%') const;
+#else
+ [[nodiscard]] QByteArray percentDecoded(char percent = '%') const &
+ { return fromPercentEncoding(*this, percent); }
+ [[nodiscard]] QByteArray percentDecoded(char percent = '%') &&
+ { return fromPercentEncoding(std::move(*this), percent); }
+#endif
inline QByteArray &setNum(short, int base = 10);
inline QByteArray &setNum(ushort, int base = 10);
@@ -432,6 +439,7 @@ public:
[[nodiscard]] static QByteArray fromBase64(const QByteArray &base64, Base64Options options = Base64Encoding);
[[nodiscard]] static QByteArray fromHex(const QByteArray &hexEncoded);
[[nodiscard]] static QByteArray fromPercentEncoding(const QByteArray &pctEncoded, char percent = '%');
+ [[nodiscard]] static QByteArray fromPercentEncoding(QByteArray &&pctEncoded, char percent = '%');
#if defined(Q_OS_DARWIN) || defined(Q_QDOC)
static QByteArray fromCFData(CFDataRef data);
diff --git a/src/corelib/text/qlatin1stringview.h b/src/corelib/text/qlatin1stringview.h
index d76c5da512b..0e9e4fb3699 100644
--- a/src/corelib/text/qlatin1stringview.h
+++ b/src/corelib/text/qlatin1stringview.h
@@ -8,6 +8,7 @@
#ifndef QLATIN1STRINGVIEW_H
#define QLATIN1STRINGVIEW_H
+#include <QtCore/qbytearrayview.h>
#include <QtCore/qchar.h>
#include <QtCore/qcompare.h>
#include <QtCore/qcontainerfwd.h>
@@ -124,8 +125,14 @@ public:
{ return QtPrivate::findString(*this, from, s, cs); }
[[nodiscard]] qsizetype indexOf(QLatin1StringView s, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::findString(*this, from, s, cs); }
- [[nodiscard]] qsizetype indexOf(QChar c, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
- { return QtPrivate::findString(*this, from, QStringView(&c, 1), cs); }
+ [[nodiscard]] qsizetype indexOf(QChar c, qsizetype from = 0) const noexcept
+ { return c.unicode() <= 0xff ? QByteArrayView(*this).indexOf(char(c.unicode()), from) : -1; }
+ [[nodiscard]] qsizetype indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const noexcept
+ {
+ if (cs == Qt::CaseInsensitive)
+ return QtPrivate::findString(*this, from, QStringView(&c, 1), cs);
+ return indexOf(c, from);
+ }
[[nodiscard]] bool contains(QStringView s, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return indexOf(s, 0, cs) != -1; }
@@ -142,10 +149,18 @@ public:
{ return lastIndexOf(s, size(), cs); }
[[nodiscard]] qsizetype lastIndexOf(QLatin1StringView s, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
{ return QtPrivate::lastIndexOf(*this, from, s, cs); }
- [[nodiscard]] qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ [[nodiscard]] qsizetype lastIndexOf(QChar c) const noexcept
+ { return lastIndexOf(c, -1); }
+ [[nodiscard]] qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs) const noexcept
{ return lastIndexOf(c, -1, cs); }
- [[nodiscard]] qsizetype lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
- { return QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs); }
+ [[nodiscard]] qsizetype lastIndexOf(QChar c, qsizetype from) const noexcept
+ { return c.unicode() <= 0xff ? QByteArrayView(*this).lastIndexOf(char(c.unicode()), from) : -1; }
+ [[nodiscard]] qsizetype lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const noexcept
+ {
+ if (cs == Qt::CaseInsensitive)
+ return QtPrivate::lastIndexOf(*this, from, QStringView(&c, 1), cs);
+ return lastIndexOf(c, from);
+ }
[[nodiscard]] qsizetype count(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
{ return QtPrivate::count(*this, str, cs); }
diff --git a/src/corelib/text/qlatin1stringview.qdoc b/src/corelib/text/qlatin1stringview.qdoc
index d28b61c4276..a36d7233c59 100644
--- a/src/corelib/text/qlatin1stringview.qdoc
+++ b/src/corelib/text/qlatin1stringview.qdoc
@@ -505,7 +505,8 @@
/*!
\fn qsizetype QLatin1StringView::indexOf(QStringView str, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
\fn qsizetype QLatin1StringView::indexOf(QLatin1StringView l1, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
- \fn qsizetype QLatin1StringView::indexOf(QChar c, qsizetype from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive) const
+ \fn qsizetype QLatin1StringView::indexOf(QChar c, qsizetype from = 0) const
+ \fn qsizetype QLatin1StringView::indexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const
\since 5.14
Returns the index position in this Latin-1 string view of the first
@@ -540,6 +541,9 @@
/*!
\fn qsizetype QLatin1StringView::lastIndexOf(QStringView str, qsizetype from, Qt::CaseSensitivity cs) const
\fn qsizetype QLatin1StringView::lastIndexOf(QLatin1StringView l1, qsizetype from, Qt::CaseSensitivity cs) const
+ \fn qsizetype QLatin1StringView::lastIndexOf(QChar c) const
+ \fn qsizetype QLatin1StringView::lastIndexOf(QChar c, Qt::CaseSensitivity cs) const
+ \fn qsizetype QLatin1StringView::lastIndexOf(QChar c, qsizetype from) const
\fn qsizetype QLatin1StringView::lastIndexOf(QChar c, qsizetype from, Qt::CaseSensitivity cs) const
\since 5.14
diff --git a/src/corelib/text/qstring.cpp b/src/corelib/text/qstring.cpp
index 46c01bf232a..c01c1a9999d 100644
--- a/src/corelib/text/qstring.cpp
+++ b/src/corelib/text/qstring.cpp
@@ -3681,95 +3681,24 @@ QString &QString::remove(QChar ch, Qt::CaseSensitivity cs)
\sa remove()
*/
-
-/*! \internal
- Instead of detaching, or reallocating if "before" is shorter than "after"
- and there isn't enough capacity, create a new string, copy characters to it
- as needed, then swap it with "str".
-*/
-static void replace_with_copy(QString &str, QSpan<size_t> indices, qsizetype blen,
- QStringView after)
-{
- const qsizetype alen = after.size();
- const char16_t *after_b = after.utf16();
-
- const QString::DataPointer &str_d = str.data_ptr();
- auto src_start = str_d.begin();
- const qsizetype newSize = str_d.size + indices.size() * (alen - blen);
- QString copy{ newSize, Qt::Uninitialized };
- QString::DataPointer &copy_d = copy.data_ptr();
- auto dst = copy_d.begin();
- for (size_t index : indices) {
- auto hit = str_d.begin() + index;
- dst = std::copy(src_start, hit, dst);
- dst = std::copy_n(after_b, alen, dst);
- src_start = hit + blen;
- }
- dst = std::copy(src_start, str_d.end(), dst);
- str.swap(copy);
-}
-
-// No detaching or reallocation is needed
-static void replace_in_place(QString &str, QSpan<size_t> indices,
- qsizetype blen, QStringView after)
-{
- const qsizetype alen = after.size();
- const char16_t *after_b = after.utf16();
- const char16_t *after_e = after.utf16() + after.size();
-
- if (blen == alen) { // Replace in place
- for (size_t index : indices)
- std::copy_n(after_b, alen, str.data_ptr().begin() + index);
- } else if (blen > alen) { // Replace from front
- char16_t *begin = str.data_ptr().begin();
- char16_t *hit = begin + indices.front();
- char16_t *to = hit;
- to = std::copy_n(after_b, alen, to);
- char16_t *movestart = hit + blen;
- for (size_t index : indices.sliced(1)) {
- hit = begin + index;
- to = std::move(movestart, hit, to);
- to = std::copy_n(after_b, alen, to);
- movestart = hit + blen;
- }
- to = std::move(movestart, str.data_ptr().end(), to);
- str.resize(std::distance(begin, to));
- } else { // blen < alen, Replace from back
- const qsizetype oldSize = str.data_ptr().size;
- const qsizetype adjust = indices.size() * (alen - blen);
- const qsizetype newSize = oldSize + adjust;
-
- str.resize(newSize);
- char16_t *begin = str.data_ptr().begin();
- char16_t *moveend = begin + oldSize;
- char16_t *to = str.data_ptr().end();
-
- for (auto it = indices.rbegin(), end = indices.rend(); it != end; ++it) {
- char16_t *hit = begin + *it;
- char16_t *movestart = hit + blen;
- to = std::move_backward(movestart, moveend, to);
- to = std::copy_backward(after_b, after_e, to);
- moveend = hit;
- }
- }
-}
-
-static void replace_helper(QString &str, QSpan<size_t> indices, qsizetype blen, QStringView after)
+static void replace_helper(QString &str, QSpan<qsizetype> indices, qsizetype blen, QStringView after)
{
const qsizetype oldSize = str.data_ptr().size;
const qsizetype adjust = indices.size() * (after.size() - blen);
const qsizetype newSize = oldSize + adjust;
+ using A = QStringAlgorithms<QString>;
if (str.data_ptr().needsDetach() || needsReallocate(str, newSize)) {
- replace_with_copy(str, indices, blen, after);
+ A::replace_helper(str, blen, after, indices);
return;
}
- if (QtPrivate::q_points_into_range(after.begin(), str))
+ if (QtPrivate::q_points_into_range(after.begin(), str)) {
// Copy after if it lies inside our own d.b area (which we could
// possibly invalidate via a realloc or modify by replacement)
- replace_in_place(str, indices, blen, QVarLengthArray(after.begin(), after.end()));
- else
- replace_in_place(str, indices, blen, after);
+ A::replace_helper(str, blen, QVarLengthArray(after.begin(), after.end()), indices);
+ } else {
+ A::replace_helper(str, blen, after, indices);
+ }
}
/*!
@@ -3811,8 +3740,8 @@ QString &QString::replace(qsizetype pos, qsizetype len, const QChar *after, qsiz
if (len > this->size() - pos)
len = this->size() - pos;
- size_t index = pos;
- replace_helper(*this, QSpan(&index, 1), len, QStringView{after, alen});
+ qsizetype indices[] = {pos};
+ replace_helper(*this, indices, len, QStringView{after, alen});
return *this;
}
@@ -3890,7 +3819,7 @@ QString &QString::replace(const QChar *before, qsizetype blen,
qsizetype index = 0;
- QVarLengthArray<size_t> indices;
+ QVarLengthArray<qsizetype> indices;
while ((index = matcher.indexIn(*this, index)) != -1) {
indices.push_back(index);
if (blen) // Step over before:
@@ -3925,7 +3854,7 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
const char16_t cc = (cs == Qt::CaseSensitive ? ch.unicode() : ch.toCaseFolded().unicode());
- QVarLengthArray<size_t> indices;
+ QVarLengthArray<qsizetype> indices;
if (cs == Qt::CaseSensitive) {
const char16_t *begin = d.begin();
const char16_t *end = d.end();
@@ -7328,6 +7257,12 @@ QString QString::toCaseFolded_helper(QString &str)
\note In some cases the uppercase form of a string may be longer than the
original.
+ \note Since 2024, the German language officially prefers to uppercase ß
+ (U+00DF LATIN SMALL LETTER SHARP S) as ẞ (U+1E9E LATIN CAPITAL LETTER SHARP S).
+ Qt's implementation follows Unicode, which still mandates the use of "SS".
+ If you need to implement the new German rules, you need to manually do
+ \c{replace(u'ß', u'ẞ')} \e{before} calling this function.
+
\sa toLower(), QLocale::toLower()
*/
diff --git a/src/corelib/text/qstringiterator_p.h b/src/corelib/text/qstringiterator_p.h
index 38a1216bdb8..3c9658bd92f 100644
--- a/src/corelib/text/qstringiterator_p.h
+++ b/src/corelib/text/qstringiterator_p.h
@@ -148,6 +148,17 @@ public:
return uc.unicode();
}
+ char32_t nextOrRawCodeUnit()
+ {
+ Q_ASSERT_X(hasNext(), Q_FUNC_INFO, "iterator hasn't a next item");
+
+ const QChar uc = *pos++;
+ if (uc.isHighSurrogate() && hasNext() && pos->isLowSurrogate())
+ return QChar::surrogateToUcs4(uc, *pos++);
+
+ return uc.unicode();
+ }
+
// backwards iteration
inline bool hasPrevious() const
@@ -228,6 +239,17 @@ public:
return uc.unicode();
}
+
+ char32_t previousOrRawCodeUnit()
+ {
+ Q_ASSERT_X(hasPrevious(), Q_FUNC_INFO, "iterator hasn't a previous item");
+
+ const QChar uc = *--pos;
+ if (uc.isLowSurrogate() && hasPrevious() && pos[-1].isHighSurrogate())
+ return QChar::surrogateToUcs4(*--pos, uc);
+
+ return uc.unicode();
+ }
};
QT_END_NAMESPACE
diff --git a/src/corelib/text/qunicodetables.cpp b/src/corelib/text/qunicodetables.cpp
index 22a665089e3..eb4f8b9cb7a 100644
--- a/src/corelib/text/qunicodetables.cpp
+++ b/src/corelib/text/qunicodetables.cpp
@@ -9,6 +9,457 @@
QT_BEGIN_NAMESPACE
namespace QUnicodeTables {
+static constexpr std::array<CaseConversion, NumCases> caseConversions[] = {
+ { { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 0, 32 }, { 0, 0 }, { 0, 0 }, { 0, 32 } } },
+ { { { 0, 0 }, { 0, -32 }, { 0, -32 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 743 }, { 0, 743 }, { 0, 775 } } },
+ { { { 0, 0 }, { 1, 426 }, { 1, 423 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 121 }, { 0, 121 }, { 0, 0 } } },
+ { { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } } },
+ { { { 0, 0 }, { 0, -1 }, { 0, -1 }, { 0, 0 } } },
+ { { { 1, 429 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -232 }, { 0, -232 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 508 }, { 1, 508 }, { 0, 0 } } },
+ { { { 0, -121 }, { 0, 0 }, { 0, 0 }, { 0, -121 } } },
+ { { { 0, 0 }, { 0, -300 }, { 0, -300 }, { 0, -268 } } },
+ { { { 0, 0 }, { 0, 195 }, { 0, 195 }, { 0, 0 } } },
+ { { { 0, 210 }, { 0, 0 }, { 0, 0 }, { 0, 210 } } },
+ { { { 0, 206 }, { 0, 0 }, { 0, 0 }, { 0, 206 } } },
+ { { { 0, 205 }, { 0, 0 }, { 0, 0 }, { 0, 205 } } },
+ { { { 0, 79 }, { 0, 0 }, { 0, 0 }, { 0, 79 } } },
+ { { { 0, 202 }, { 0, 0 }, { 0, 0 }, { 0, 202 } } },
+ { { { 0, 203 }, { 0, 0 }, { 0, 0 }, { 0, 203 } } },
+ { { { 0, 207 }, { 0, 0 }, { 0, 0 }, { 0, 207 } } },
+ { { { 0, 0 }, { 0, 97 }, { 0, 97 }, { 0, 0 } } },
+ { { { 0, 211 }, { 0, 0 }, { 0, 0 }, { 0, 211 } } },
+ { { { 0, 209 }, { 0, 0 }, { 0, 0 }, { 0, 209 } } },
+ { { { 0, 0 }, { 0, 163 }, { 0, 163 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 1 }, { 1, 1 }, { 0, 0 } } },
+ { { { 0, 213 }, { 0, 0 }, { 0, 0 }, { 0, 213 } } },
+ { { { 0, 0 }, { 0, 130 }, { 0, 130 }, { 0, 0 } } },
+ { { { 0, 214 }, { 0, 0 }, { 0, 0 }, { 0, 214 } } },
+ { { { 0, 218 }, { 0, 0 }, { 0, 0 }, { 0, 218 } } },
+ { { { 0, 217 }, { 0, 0 }, { 0, 0 }, { 0, 217 } } },
+ { { { 0, 219 }, { 0, 0 }, { 0, 0 }, { 0, 219 } } },
+ { { { 0, 0 }, { 0, 56 }, { 0, 56 }, { 0, 0 } } },
+ { { { 0, 2 }, { 0, 0 }, { 0, 1 }, { 0, 2 } } },
+ { { { 0, 1 }, { 0, -1 }, { 0, 0 }, { 0, 1 } } },
+ { { { 0, 0 }, { 0, -2 }, { 0, -1 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -79 }, { 0, -79 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 519 }, { 1, 519 }, { 0, 0 } } },
+ { { { 0, -97 }, { 0, 0 }, { 0, 0 }, { 0, -97 } } },
+ { { { 0, -56 }, { 0, 0 }, { 0, 0 }, { 0, -56 } } },
+ { { { 0, -130 }, { 0, 0 }, { 0, 0 }, { 0, -130 } } },
+ { { { 1, 3 }, { 0, 0 }, { 0, 0 }, { 1, 3 } } },
+ { { { 0, -163 }, { 0, 0 }, { 0, 0 }, { 0, -163 } } },
+ { { { 1, 5 }, { 0, 0 }, { 0, 0 }, { 1, 5 } } },
+ { { { 0, 0 }, { 1, 7 }, { 1, 7 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 9 }, { 1, 9 }, { 0, 0 } } },
+ { { { 0, -195 }, { 0, 0 }, { 0, 0 }, { 0, -195 } } },
+ { { { 0, 69 }, { 0, 0 }, { 0, 0 }, { 0, 69 } } },
+ { { { 0, 71 }, { 0, 0 }, { 0, 0 }, { 0, 71 } } },
+ { { { 0, 0 }, { 1, 11 }, { 1, 11 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 13 }, { 1, 13 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 15 }, { 1, 15 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -210 }, { 0, -210 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -206 }, { 0, -206 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -205 }, { 0, -205 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -202 }, { 0, -202 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -203 }, { 0, -203 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 17 }, { 1, 17 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 19 }, { 1, 19 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -207 }, { 0, -207 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 21 }, { 1, 21 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 23 }, { 1, 23 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 25 }, { 1, 25 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -209 }, { 0, -209 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -211 }, { 0, -211 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 27 }, { 1, 27 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 29 }, { 1, 29 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 31 }, { 1, 31 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 33 }, { 1, 33 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -213 }, { 0, -213 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -214 }, { 0, -214 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 35 }, { 1, 35 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -218 }, { 0, -218 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 37 }, { 1, 37 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 39 }, { 1, 39 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -69 }, { 0, -69 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -217 }, { 0, -217 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -71 }, { 0, -71 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -219 }, { 0, -219 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 41 }, { 1, 41 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 43 }, { 1, 43 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 84 }, { 0, 84 }, { 0, 116 } } },
+ { { { 0, 116 }, { 0, 0 }, { 0, 0 }, { 0, 116 } } },
+ { { { 0, 38 }, { 0, 0 }, { 0, 0 }, { 0, 38 } } },
+ { { { 0, 37 }, { 0, 0 }, { 0, 0 }, { 0, 37 } } },
+ { { { 0, 64 }, { 0, 0 }, { 0, 0 }, { 0, 64 } } },
+ { { { 0, 63 }, { 0, 0 }, { 0, 0 }, { 0, 63 } } },
+ { { { 0, 0 }, { 1, 511 }, { 1, 511 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -38 }, { 0, -38 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -37 }, { 0, -37 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 515 }, { 1, 515 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -31 }, { 0, -31 }, { 0, 1 } } },
+ { { { 0, 0 }, { 0, -64 }, { 0, -64 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -63 }, { 0, -63 }, { 0, 0 } } },
+ { { { 0, 8 }, { 0, 0 }, { 0, 0 }, { 0, 8 } } },
+ { { { 0, 0 }, { 0, -62 }, { 0, -62 }, { 0, -30 } } },
+ { { { 0, 0 }, { 0, -57 }, { 0, -57 }, { 0, -25 } } },
+ { { { 0, 0 }, { 0, -47 }, { 0, -47 }, { 0, -15 } } },
+ { { { 0, 0 }, { 0, -54 }, { 0, -54 }, { 0, -22 } } },
+ { { { 0, 0 }, { 0, -8 }, { 0, -8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -86 }, { 0, -86 }, { 0, -54 } } },
+ { { { 0, 0 }, { 0, -80 }, { 0, -80 }, { 0, -48 } } },
+ { { { 0, 0 }, { 0, 7 }, { 0, 7 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -116 }, { 0, -116 }, { 0, 0 } } },
+ { { { 0, -60 }, { 0, 0 }, { 0, 0 }, { 0, -60 } } },
+ { { { 0, 0 }, { 0, -96 }, { 0, -96 }, { 0, -64 } } },
+ { { { 0, -7 }, { 0, 0 }, { 0, 0 }, { 0, -7 } } },
+ { { { 0, 80 }, { 0, 0 }, { 0, 0 }, { 0, 80 } } },
+ { { { 0, 0 }, { 0, -80 }, { 0, -80 }, { 0, 0 } } },
+ { { { 0, 15 }, { 0, 0 }, { 0, 0 }, { 0, 15 } } },
+ { { { 0, 0 }, { 0, -15 }, { 0, -15 }, { 0, 0 } } },
+ { { { 0, 48 }, { 0, 0 }, { 0, 0 }, { 0, 48 } } },
+ { { { 0, 0 }, { 0, -48 }, { 0, -48 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 475 }, { 1, 472 }, { 0, 0 } } },
+ { { { 0, 7264 }, { 0, 0 }, { 0, 0 }, { 0, 7264 } } },
+ { { { 0, 0 }, { 0, 3008 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 45 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 47 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 49 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 51 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 53 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 55 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 57 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 59 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 61 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 63 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 65 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 67 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 69 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 71 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 73 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 75 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 77 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 79 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 81 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 83 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 85 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 87 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 89 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 91 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 93 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 95 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 97 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 99 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 101 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 103 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 105 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 107 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 109 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 111 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 113 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 115 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 117 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 119 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 121 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 123 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 125 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 127 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 129 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 131 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 133 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 135 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 137 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 139 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 141 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 143 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 145 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 147 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 149 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 151 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 153 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 155 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 157 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 159 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 161 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 163 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 165 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 167 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 169 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 171 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 173 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 175 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 177 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 179 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 181 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 183 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 185 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 187 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 189 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 191 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 193 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 195 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 197 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 199 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 201 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 1, 203 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 0, 8 }, { 0, 0 }, { 0, 0 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -8 }, { 0, -8 }, { 0, -8 } } },
+ { { { 0, 0 }, { 0, -6254 }, { 0, -6254 }, { 0, -6222 } } },
+ { { { 0, 0 }, { 0, -6253 }, { 0, -6253 }, { 0, -6221 } } },
+ { { { 0, 0 }, { 0, -6244 }, { 0, -6244 }, { 0, -6212 } } },
+ { { { 0, 0 }, { 0, -6242 }, { 0, -6242 }, { 0, -6210 } } },
+ { { { 0, 0 }, { 0, -6243 }, { 0, -6243 }, { 0, -6211 } } },
+ { { { 0, 0 }, { 0, -6236 }, { 0, -6236 }, { 0, -6204 } } },
+ { { { 0, 0 }, { 0, -6181 }, { 0, -6181 }, { 0, -6180 } } },
+ { { { 0, 0 }, { 1, 205 }, { 1, 205 }, { 1, 727 } } },
+ { { { 0, -3008 }, { 0, 0 }, { 0, 0 }, { 0, -3008 } } },
+ { { { 0, 0 }, { 1, 207 }, { 1, 207 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 3814 }, { 0, 3814 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 209 }, { 1, 209 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 522 }, { 1, 522 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 525 }, { 1, 525 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 528 }, { 1, 528 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 531 }, { 1, 531 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 534 }, { 1, 534 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, -59 }, { 0, -59 }, { 0, -58 } } },
+ { { { 0, -7615 }, { 0, 0 }, { 0, 0 }, { 0, -7615 } } },
+ { { { 0, 0 }, { 0, 8 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, -8 }, { 0, 0 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, 0 }, { 1, 537 }, { 1, 537 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 540 }, { 1, 540 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 544 }, { 1, 544 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 548 }, { 1, 548 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 74 }, { 0, 74 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 86 }, { 0, 86 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 100 }, { 0, 100 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 128 }, { 0, 128 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 112 }, { 0, 112 }, { 0, 0 } } },
+ { { { 0, 0 }, { 0, 126 }, { 0, 126 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 586 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 589 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 592 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 595 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 598 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 601 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 604 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 607 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, -8 }, { 1, 586 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 589 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 592 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 595 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 598 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 601 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 604 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 607 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, 0 }, { 1, 610 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 613 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 616 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 619 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 622 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 625 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 628 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 631 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, -8 }, { 1, 610 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 613 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 616 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 619 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 622 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 625 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 628 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 631 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, 0 }, { 1, 634 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 637 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 640 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 643 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 646 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 649 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 652 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 655 }, { 0, 8 }, { 0, 0 } } },
+ { { { 0, -8 }, { 1, 634 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 637 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 640 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 643 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 646 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 649 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 652 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, -8 }, { 1, 655 }, { 0, 0 }, { 0, -8 } } },
+ { { { 0, 0 }, { 1, 670 }, { 1, 667 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 658 }, { 0, 9 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 676 }, { 1, 673 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 552 }, { 1, 552 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 707 }, { 1, 703 }, { 0, 0 } } },
+ { { { 0, -74 }, { 0, 0 }, { 0, 0 }, { 0, -74 } } },
+ { { { 0, -9 }, { 1, 658 }, { 0, 0 }, { 0, -9 } } },
+ { { { 0, 0 }, { 0, -7205 }, { 0, -7205 }, { 0, -7173 } } },
+ { { { 0, 0 }, { 1, 682 }, { 1, 679 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 661 }, { 0, 9 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 688 }, { 1, 685 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 555 }, { 1, 555 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 715 }, { 1, 711 }, { 0, 0 } } },
+ { { { 0, -86 }, { 0, 0 }, { 0, 0 }, { 0, -86 } } },
+ { { { 0, -9 }, { 1, 661 }, { 0, 0 }, { 0, -9 } } },
+ { { { 0, 0 }, { 1, 558 }, { 1, 558 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 511 }, { 1, 511 }, { 0, -7235 } } },
+ { { { 0, 0 }, { 1, 562 }, { 1, 562 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 565 }, { 1, 565 }, { 0, 0 } } },
+ { { { 0, -100 }, { 0, 0 }, { 0, 0 }, { 0, -100 } } },
+ { { { 0, 0 }, { 1, 569 }, { 1, 569 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 515 }, { 1, 515 }, { 0, -7219 } } },
+ { { { 0, 0 }, { 1, 573 }, { 1, 573 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 576 }, { 1, 576 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 579 }, { 1, 579 }, { 0, 0 } } },
+ { { { 0, -112 }, { 0, 0 }, { 0, 0 }, { 0, -112 } } },
+ { { { 0, 0 }, { 1, 694 }, { 1, 691 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 664 }, { 0, 9 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 700 }, { 1, 697 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 583 }, { 1, 583 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 723 }, { 1, 719 }, { 0, 0 } } },
+ { { { 0, -128 }, { 0, 0 }, { 0, 0 }, { 0, -128 } } },
+ { { { 0, -126 }, { 0, 0 }, { 0, 0 }, { 0, -126 } } },
+ { { { 0, -9 }, { 1, 664 }, { 0, 0 }, { 0, -9 } } },
+ { { { 0, -7517 }, { 0, 0 }, { 0, 0 }, { 0, -7517 } } },
+ { { { 1, 211 }, { 0, 0 }, { 0, 0 }, { 1, 211 } } },
+ { { { 1, 213 }, { 0, 0 }, { 0, 0 }, { 1, 213 } } },
+ { { { 0, 28 }, { 0, 0 }, { 0, 0 }, { 0, 28 } } },
+ { { { 0, 0 }, { 0, -28 }, { 0, -28 }, { 0, 0 } } },
+ { { { 0, 16 }, { 0, 0 }, { 0, 0 }, { 0, 16 } } },
+ { { { 0, 0 }, { 0, -16 }, { 0, -16 }, { 0, 0 } } },
+ { { { 0, 26 }, { 0, 0 }, { 0, 0 }, { 0, 26 } } },
+ { { { 0, 0 }, { 0, -26 }, { 0, -26 }, { 0, 0 } } },
+ { { { 1, 215 }, { 0, 0 }, { 0, 0 }, { 1, 215 } } },
+ { { { 0, -3814 }, { 0, 0 }, { 0, 0 }, { 0, -3814 } } },
+ { { { 1, 217 }, { 0, 0 }, { 0, 0 }, { 1, 217 } } },
+ { { { 0, 0 }, { 1, 219 }, { 1, 219 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 221 }, { 1, 221 }, { 0, 0 } } },
+ { { { 1, 223 }, { 0, 0 }, { 0, 0 }, { 1, 223 } } },
+ { { { 1, 225 }, { 0, 0 }, { 0, 0 }, { 1, 225 } } },
+ { { { 1, 227 }, { 0, 0 }, { 0, 0 }, { 1, 227 } } },
+ { { { 1, 229 }, { 0, 0 }, { 0, 0 }, { 1, 229 } } },
+ { { { 1, 231 }, { 0, 0 }, { 0, 0 }, { 1, 231 } } },
+ { { { 1, 233 }, { 0, 0 }, { 0, 0 }, { 1, 233 } } },
+ { { { 0, 0 }, { 0, -7264 }, { 0, -7264 }, { 0, 0 } } },
+ { { { 1, 235 }, { 0, 0 }, { 0, 0 }, { 1, 235 } } },
+ { { { 1, 237 }, { 0, 0 }, { 0, 0 }, { 1, 237 } } },
+ { { { 0, 0 }, { 0, 48 }, { 0, 48 }, { 0, 0 } } },
+ { { { 1, 239 }, { 0, 0 }, { 0, 0 }, { 1, 239 } } },
+ { { { 1, 241 }, { 0, 0 }, { 0, 0 }, { 1, 241 } } },
+ { { { 1, 243 }, { 0, 0 }, { 0, 0 }, { 1, 243 } } },
+ { { { 1, 245 }, { 0, 0 }, { 0, 0 }, { 1, 245 } } },
+ { { { 1, 247 }, { 0, 0 }, { 0, 0 }, { 1, 247 } } },
+ { { { 1, 249 }, { 0, 0 }, { 0, 0 }, { 1, 249 } } },
+ { { { 1, 251 }, { 0, 0 }, { 0, 0 }, { 1, 251 } } },
+ { { { 1, 253 }, { 0, 0 }, { 0, 0 }, { 1, 253 } } },
+ { { { 0, 928 }, { 0, 0 }, { 0, 0 }, { 0, 928 } } },
+ { { { 0, -48 }, { 0, 0 }, { 0, 0 }, { 0, -48 } } },
+ { { { 1, 255 }, { 0, 0 }, { 0, 0 }, { 1, 255 } } },
+ { { { 1, 257 }, { 0, 0 }, { 0, 0 }, { 1, 257 } } },
+ { { { 1, 259 }, { 0, 0 }, { 0, 0 }, { 1, 259 } } },
+ { { { 1, 261 }, { 0, 0 }, { 0, 0 }, { 1, 261 } } },
+ { { { 0, 0 }, { 0, -928 }, { 0, -928 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 263 }, { 1, 263 }, { 1, 263 } } },
+ { { { 0, 0 }, { 1, 265 }, { 1, 265 }, { 1, 265 } } },
+ { { { 0, 0 }, { 1, 267 }, { 1, 267 }, { 1, 267 } } },
+ { { { 0, 0 }, { 1, 269 }, { 1, 269 }, { 1, 269 } } },
+ { { { 0, 0 }, { 1, 271 }, { 1, 271 }, { 1, 271 } } },
+ { { { 0, 0 }, { 1, 273 }, { 1, 273 }, { 1, 273 } } },
+ { { { 0, 0 }, { 1, 275 }, { 1, 275 }, { 1, 275 } } },
+ { { { 0, 0 }, { 1, 277 }, { 1, 277 }, { 1, 277 } } },
+ { { { 0, 0 }, { 1, 279 }, { 1, 279 }, { 1, 279 } } },
+ { { { 0, 0 }, { 1, 281 }, { 1, 281 }, { 1, 281 } } },
+ { { { 0, 0 }, { 1, 283 }, { 1, 283 }, { 1, 283 } } },
+ { { { 0, 0 }, { 1, 285 }, { 1, 285 }, { 1, 285 } } },
+ { { { 0, 0 }, { 1, 287 }, { 1, 287 }, { 1, 287 } } },
+ { { { 0, 0 }, { 1, 289 }, { 1, 289 }, { 1, 289 } } },
+ { { { 0, 0 }, { 1, 291 }, { 1, 291 }, { 1, 291 } } },
+ { { { 0, 0 }, { 1, 293 }, { 1, 293 }, { 1, 293 } } },
+ { { { 0, 0 }, { 1, 295 }, { 1, 295 }, { 1, 295 } } },
+ { { { 0, 0 }, { 1, 297 }, { 1, 297 }, { 1, 297 } } },
+ { { { 0, 0 }, { 1, 299 }, { 1, 299 }, { 1, 299 } } },
+ { { { 0, 0 }, { 1, 301 }, { 1, 301 }, { 1, 301 } } },
+ { { { 0, 0 }, { 1, 303 }, { 1, 303 }, { 1, 303 } } },
+ { { { 0, 0 }, { 1, 305 }, { 1, 305 }, { 1, 305 } } },
+ { { { 0, 0 }, { 1, 307 }, { 1, 307 }, { 1, 307 } } },
+ { { { 0, 0 }, { 1, 309 }, { 1, 309 }, { 1, 309 } } },
+ { { { 0, 0 }, { 1, 311 }, { 1, 311 }, { 1, 311 } } },
+ { { { 0, 0 }, { 1, 313 }, { 1, 313 }, { 1, 313 } } },
+ { { { 0, 0 }, { 1, 315 }, { 1, 315 }, { 1, 315 } } },
+ { { { 0, 0 }, { 1, 317 }, { 1, 317 }, { 1, 317 } } },
+ { { { 0, 0 }, { 1, 319 }, { 1, 319 }, { 1, 319 } } },
+ { { { 0, 0 }, { 1, 321 }, { 1, 321 }, { 1, 321 } } },
+ { { { 0, 0 }, { 1, 323 }, { 1, 323 }, { 1, 323 } } },
+ { { { 0, 0 }, { 1, 325 }, { 1, 325 }, { 1, 325 } } },
+ { { { 0, 0 }, { 1, 327 }, { 1, 327 }, { 1, 327 } } },
+ { { { 0, 0 }, { 1, 329 }, { 1, 329 }, { 1, 329 } } },
+ { { { 0, 0 }, { 1, 331 }, { 1, 331 }, { 1, 331 } } },
+ { { { 0, 0 }, { 1, 333 }, { 1, 333 }, { 1, 333 } } },
+ { { { 0, 0 }, { 1, 335 }, { 1, 335 }, { 1, 335 } } },
+ { { { 0, 0 }, { 1, 337 }, { 1, 337 }, { 1, 337 } } },
+ { { { 0, 0 }, { 1, 339 }, { 1, 339 }, { 1, 339 } } },
+ { { { 0, 0 }, { 1, 341 }, { 1, 341 }, { 1, 341 } } },
+ { { { 0, 0 }, { 1, 343 }, { 1, 343 }, { 1, 343 } } },
+ { { { 0, 0 }, { 1, 345 }, { 1, 345 }, { 1, 345 } } },
+ { { { 0, 0 }, { 1, 347 }, { 1, 347 }, { 1, 347 } } },
+ { { { 0, 0 }, { 1, 349 }, { 1, 349 }, { 1, 349 } } },
+ { { { 0, 0 }, { 1, 351 }, { 1, 351 }, { 1, 351 } } },
+ { { { 0, 0 }, { 1, 353 }, { 1, 353 }, { 1, 353 } } },
+ { { { 0, 0 }, { 1, 355 }, { 1, 355 }, { 1, 355 } } },
+ { { { 0, 0 }, { 1, 357 }, { 1, 357 }, { 1, 357 } } },
+ { { { 0, 0 }, { 1, 359 }, { 1, 359 }, { 1, 359 } } },
+ { { { 0, 0 }, { 1, 361 }, { 1, 361 }, { 1, 361 } } },
+ { { { 0, 0 }, { 1, 363 }, { 1, 363 }, { 1, 363 } } },
+ { { { 0, 0 }, { 1, 365 }, { 1, 365 }, { 1, 365 } } },
+ { { { 0, 0 }, { 1, 367 }, { 1, 367 }, { 1, 367 } } },
+ { { { 0, 0 }, { 1, 369 }, { 1, 369 }, { 1, 369 } } },
+ { { { 0, 0 }, { 1, 371 }, { 1, 371 }, { 1, 371 } } },
+ { { { 0, 0 }, { 1, 373 }, { 1, 373 }, { 1, 373 } } },
+ { { { 0, 0 }, { 1, 375 }, { 1, 375 }, { 1, 375 } } },
+ { { { 0, 0 }, { 1, 377 }, { 1, 377 }, { 1, 377 } } },
+ { { { 0, 0 }, { 1, 379 }, { 1, 379 }, { 1, 379 } } },
+ { { { 0, 0 }, { 1, 381 }, { 1, 381 }, { 1, 381 } } },
+ { { { 0, 0 }, { 1, 383 }, { 1, 383 }, { 1, 383 } } },
+ { { { 0, 0 }, { 1, 385 }, { 1, 385 }, { 1, 385 } } },
+ { { { 0, 0 }, { 1, 387 }, { 1, 387 }, { 1, 387 } } },
+ { { { 0, 0 }, { 1, 389 }, { 1, 389 }, { 1, 389 } } },
+ { { { 0, 0 }, { 1, 391 }, { 1, 391 }, { 1, 391 } } },
+ { { { 0, 0 }, { 1, 393 }, { 1, 393 }, { 1, 393 } } },
+ { { { 0, 0 }, { 1, 395 }, { 1, 395 }, { 1, 395 } } },
+ { { { 0, 0 }, { 1, 397 }, { 1, 397 }, { 1, 397 } } },
+ { { { 0, 0 }, { 1, 399 }, { 1, 399 }, { 1, 399 } } },
+ { { { 0, 0 }, { 1, 401 }, { 1, 401 }, { 1, 401 } } },
+ { { { 0, 0 }, { 1, 403 }, { 1, 403 }, { 1, 403 } } },
+ { { { 0, 0 }, { 1, 405 }, { 1, 405 }, { 1, 405 } } },
+ { { { 0, 0 }, { 1, 407 }, { 1, 407 }, { 1, 407 } } },
+ { { { 0, 0 }, { 1, 409 }, { 1, 409 }, { 1, 409 } } },
+ { { { 0, 0 }, { 1, 411 }, { 1, 411 }, { 1, 411 } } },
+ { { { 0, 0 }, { 1, 413 }, { 1, 413 }, { 1, 413 } } },
+ { { { 0, 0 }, { 1, 415 }, { 1, 415 }, { 1, 415 } } },
+ { { { 0, 0 }, { 1, 417 }, { 1, 417 }, { 1, 417 } } },
+ { { { 0, 0 }, { 1, 419 }, { 1, 419 }, { 1, 419 } } },
+ { { { 0, 0 }, { 1, 421 }, { 1, 421 }, { 1, 421 } } },
+ { { { 0, 0 }, { 1, 435 }, { 1, 432 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 441 }, { 1, 438 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 447 }, { 1, 444 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 454 }, { 1, 450 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 462 }, { 1, 458 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 469 }, { 1, 466 }, { 0, 1 } } },
+ { { { 0, 0 }, { 1, 469 }, { 1, 466 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 481 }, { 1, 478 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 487 }, { 1, 484 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 493 }, { 1, 490 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 499 }, { 1, 496 }, { 0, 0 } } },
+ { { { 0, 0 }, { 1, 505 }, { 1, 502 }, { 0, 0 } } },
+ { { { 0, 40 }, { 0, 0 }, { 0, 0 }, { 0, 40 } } },
+ { { { 0, 0 }, { 0, -40 }, { 0, -40 }, { 0, 0 } } },
+ { { { 0, 39 }, { 0, 0 }, { 0, 0 }, { 0, 39 } } },
+ { { { 0, 0 }, { 0, -39 }, { 0, -39 }, { 0, 0 } } },
+ { { { 0, 34 }, { 0, 0 }, { 0, 0 }, { 0, 34 } } },
+ { { { 0, 0 }, { 0, -34 }, { 0, -34 }, { 0, 0 } } },
+};
+
static constexpr char32_t MaxSeparatorCodepoint = 0x3000;
static constexpr unsigned short uc_property_trie[] = {
@@ -7460,3378 +7911,3378 @@ static constexpr unsigned short uc_property_trie[] = {
};
static constexpr Properties uc_properties[] = {
- { 9, 18, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 0, 27, 0, 1, 2 },
- { 9, 8, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 0, 21, 5, 1, 2 },
- { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 2, 2, 48, 2, 1, 2 },
- { 9, 8, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 3, 49, 5, 1, 2 },
- { 9, 9, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 3, 49, 5, 1, 2 },
- { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 1, 1, 47, 1, 1, 2 },
- { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 0, 27, 0, 1, 2 },
- { 9, 8, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 0, 27, 0, 1, 2 },
- { 6, 9, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 18, 46, 5, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 12, 3, 13, 1, 2 },
- { 25, 4, 17, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 11, 3, 13, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 2, 13, 1, 2 },
- { 25, 10, 17, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 3, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 11, 1, 2 },
- { 20, 3, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 19, 11, 1, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 10, 1, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 10, 0, 1, 2 },
- { 3, 2, 17, 0, 0, 0, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 2, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 3, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 4, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 5, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 6, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 7, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 8, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 3, 2, 17, 0, 0, 9, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 11, 11, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 11, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -2, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 3 },
- { 21, 10, 0, 0, 0, -1, 2, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -2, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 2, 13, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 19, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 17, 15, 0, 1, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -2, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 9, 18, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 0, 27, 0, 0, 2 },
- { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 3, 49, 3, 0, 2 },
- { 6, 6, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 7, 5, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 23, 10, 0, 0, 0, -1, 16, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 10, 18, 0, 0, 5, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 21, 4, 2, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 4, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 4, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 26, 4, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 5, 2, 0, 0, 0, 2, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 3, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 743}, {0, 743}, {0, 775} } }, 0, 10, 15, 6, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 15, 0, 1, 2 },
- { 5, 2, 0, 0, 0, 1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 24, 10, 0, 0, 0, -1, -16, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 3 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {1, 426}, {1, 423}, {0, 0} } }, 0, 10, 15, 6, 4, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 121}, {0, 121}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 1, 429}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, -232}, {0, -232}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {1, 508}, {1, 508}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -121}, {0, 0}, {0, 0}, {0, -121} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -300}, {0, -300}, {0, -268} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 195}, {0, 195}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 210}, {0, 0}, {0, 0}, {0, 210} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 206}, {0, 0}, {0, 0}, {0, 206} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 205}, {0, 0}, {0, 0}, {0, 205} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 79}, {0, 0}, {0, 0}, {0, 79} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 202}, {0, 0}, {0, 0}, {0, 202} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 203}, {0, 0}, {0, 0}, {0, 203} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 207}, {0, 0}, {0, 0}, {0, 207} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 97}, {0, 97}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 211}, {0, 0}, {0, 0}, {0, 211} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 209}, {0, 0}, {0, 0}, {0, 209} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 163}, {0, 163}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 1}, {1, 1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 213}, {0, 0}, {0, 0}, {0, 213} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 130}, {0, 130}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 214}, {0, 0}, {0, 0}, {0, 214} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 218}, {0, 0}, {0, 0}, {0, 218} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 217}, {0, 0}, {0, 0}, {0, 217} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 219}, {0, 0}, {0, 0}, {0, 219} } }, 0, 10, 15, 7, 3, 3 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 56}, {0, 56}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 2}, {0, 0}, {0, 1}, {0, 2} } }, 0, 10, 15, 7, 3, 3 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 1}, {0, -1}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -2}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -79}, {0, -79}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 519}, {1, 519}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, -97}, {0, 0}, {0, 0}, {0, -97} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, -56}, {0, 0}, {0, 0}, {0, -56} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, -130}, {0, 0}, {0, 0}, {0, -130} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 1, 3}, {0, 0}, {0, 0}, {1, 3} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, -163}, {0, 0}, {0, 0}, {0, -163} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 1, 5}, {0, 0}, {0, 0}, {1, 5} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {1, 7}, {1, 7}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {1, 9}, {1, 9}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, -195}, {0, 0}, {0, 0}, {0, -195} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 69}, {0, 0}, {0, 0}, {0, 69} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 71}, {0, 0}, {0, 0}, {0, 71} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 11}, {1, 11}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {1, 13}, {1, 13}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 15}, {1, 15}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -210}, {0, -210}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -206}, {0, -206}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -205}, {0, -205}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -202}, {0, -202}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -203}, {0, -203}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 17}, {1, 17}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {1, 19}, {1, 19}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -207}, {0, -207}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 21}, {1, 21}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 23}, {1, 23}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 25}, {1, 25}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -209}, {0, -209}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -211}, {0, -211}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 27}, {1, 27}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 29}, {1, 29}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 31}, {1, 31}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 33}, {1, 33}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -213}, {0, -213}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -214}, {0, -214}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 35}, {1, 35}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -218}, {0, -218}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 37}, {1, 37}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 39}, {1, 39}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -69}, {0, -69}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -217}, {0, -217}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -71}, {0, -71}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -219}, {0, -219}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 41}, {1, 41}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {1, 43}, {1, 43}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 17, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 17, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 17, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 24, 8, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 4, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 24, 0, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 36 },
- { 17, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 0, 17, 0, 230, 5, -1, 0, 1, 0, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 232, 5, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 216, 5, -1, 0, 1, 0, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 202, 5, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 1, 0, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 202, 5, -1, 0, 1, 0, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 1, 5, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 1, 5, -1, 0, 1, 0, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 1, 0, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 3, 1 },
- { 0, 17, 0, 240, 5, -1, 0, 1, 0, 204, { { { 0, 0}, {0, 84}, {0, 84}, {0, 116} } }, 4, 4, 27, 4, 3, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 4, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 4, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 0, 5, -1, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 2, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 7, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 7, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 232, 5, -1, 0, 8, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 8, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 8, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 233, 5, -1, 0, 8, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 234, 5, -1, 0, 7, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 233, 5, -1, 0, 7, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 234, 5, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 233, 5, -1, 0, 4, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 17, 10, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 4 },
- { 13, 0, 0, 0, 0, -1, 0, 0, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 130}, {0, 130}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 11, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 116}, {0, 0}, {0, 0}, {0, 116} } }, 0, 10, 15, 7, 3, 4 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 4 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 81, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 38}, {0, 0}, {0, 0}, {0, 38} } }, 0, 10, 15, 7, 3, 4 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 15, 0, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 37}, {0, 0}, {0, 0}, {0, 37} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 64}, {0, 0}, {0, 0}, {0, 64} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 63}, {0, 0}, {0, 0}, {0, 63} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 511}, {1, 511}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -38}, {0, -38}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -37}, {0, -37}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 515}, {1, 515}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -31}, {0, -31}, {0, 1} } }, 0, 10, 15, 6, 4, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -64}, {0, -64}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -63}, {0, -63}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 8}, {0, 0}, {0, 0}, {0, 8} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -62}, {0, -62}, {0, -30} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -57}, {0, -57}, {0, -25} } }, 0, 10, 15, 6, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 81, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -47}, {0, -47}, {0, -15} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -54}, {0, -54}, {0, -22} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, -8}, {0, -8}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 46 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 46 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -86}, {0, -86}, {0, -54} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -80}, {0, -80}, {0, -48} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 7}, {0, 7}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -116}, {0, -116}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 5, 3, 80, { { { 0, -60}, {0, 0}, {0, 0}, {0, -60} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 5, 3, 80, { { { 0, 0}, {0, -96}, {0, -96}, {0, -64} } }, 0, 10, 15, 6, 3, 4 },
- { 26, 10, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 7, 3, 80, { { { 0, -7}, {0, 0}, {0, 0}, {0, -7} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, -130}, {0, 0}, {0, 0}, {0, -130} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 80}, {0, 0}, {0, 0}, {0, 80} } }, 0, 10, 15, 7, 3, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 17, { { { 0, 80}, {0, 0}, {0, 0}, {0, 80} } }, 0, 10, 15, 7, 3, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 80}, {0, 0}, {0, 0}, {0, 80} } }, 0, 10, 15, 7, 3, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 80}, {0, 0}, {0, 0}, {0, 80} } }, 0, 10, 15, 7, 3, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 17, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 0}, {0, -80}, {0, -80}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, { { { 0, 0}, {0, -80}, {0, -80}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -80}, {0, -80}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -80}, {0, -80}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 5 },
- { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 5 },
- { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 5 },
- { 2, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 15}, {0, 0}, {0, 0}, {0, 15} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, -15}, {0, -15}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 48}, {0, 0}, {0, 0}, {0, 48} } }, 0, 10, 15, 7, 3, 6 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 6 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 6 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 11, 1, 6 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 15, 0, 1, 6 },
- { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 6 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, -48}, {0, -48}, {0, 0} } }, 0, 10, 15, 6, 1, 6 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 475}, {1, 472}, {0, 0} } }, 0, 10, 15, 6, 3, 6 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 12, 1, 6 },
- { 20, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 21, 0, 1, 6 },
- { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 6 },
- { 27, 4, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 6 },
- { 13, 1, 0, 0, 0, -1, 0, 0, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 },
- { 0, 17, 0, 220, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 230, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 222, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 228, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 10, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 11, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 12, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 13, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 14, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 15, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 16, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 17, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 18, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 19, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 19, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 20, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 21, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 22, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 20, 1, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 7 },
- { 0, 17, 0, 23, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 25, 1, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 7 },
- { 0, 17, 0, 24, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 0, 17, 0, 25, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 0, 1, 7 },
- { 0, 17, 0, 18, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 18, 1, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 9, 16, 8, 1, 7 },
- { 18, 1, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 9, 16, 8, 1, 7 },
- { 25, 1, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 7 },
- { 25, 1, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 15, 0, 1, 7 },
- { 10, 5, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 8 },
- { 10, 5, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 8 },
- { 10, 5, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 26, 13, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 25, 4, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 8 },
- { 27, 13, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 8 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 11, 1, 2 },
- { 25, 13, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 11, 1, 8 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 30, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 31, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 32, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 0, 1, 2 },
- { 10, 13, 0, 0, 5, -1, 0, 15, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 8 },
- { 25, 13, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 8 },
- { 25, 13, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 8 },
- { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 2 },
- { 18, 13, 0, 0, 2, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 17, 13, 0, 0, 1, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 0, 17, 0, 27, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 28, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 29, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 30, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 31, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 32, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 33, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 34, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 4, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 4, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 220, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 3, 5, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 5, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 8 },
- { 25, 5, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 25, 5, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 14, 9, 1, 8 },
- { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 0, 17, 0, 35, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 18, 13, 0, 0, 3, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 10, 5, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 0, 17, 0, 220, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 17, 13, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 3, 2, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 3, 2, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 8 },
- { 29, 13, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 25, 13, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 12, 1, 9 },
- { 25, 13, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 9 },
- { 13, 13, 0, 0, 0, -1, 0, 0, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 },
- { 10, 13, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 15, 4, 0, 9 },
- { 18, 13, 0, 0, 3, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 9 },
- { 0, 17, 0, 36, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 9 },
- { 18, 13, 0, 0, 2, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 9 },
- { 18, 13, 0, 0, 2, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 9 },
- { 18, 13, 0, 0, 3, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 9 },
- { 0, 17, 0, 230, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 9 },
- { 0, 17, 0, 220, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 9 },
- { 18, 13, 0, 0, 2, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 10 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 10 },
- { 18, 13, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 10 },
- { 3, 1, 0, 0, 0, 0, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 2, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 3, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 4, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 5, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 6, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 7, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 8, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 3, 1, 0, 0, 0, 9, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 66 },
- { 18, 1, 0, 0, 2, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 66 },
- { 0, 17, 0, 230, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 66 },
- { 0, 17, 0, 220, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 66 },
- { 17, 1, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 66 },
- { 29, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 66 },
- { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 66 },
- { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 11, 1, 66 },
- { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 66 },
- { 17, 1, 0, 0, 1, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 66 },
- { 0, 17, 0, 220, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 66 },
- { 27, 1, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 66 },
- { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 82 },
- { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 82 },
- { 17, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 82 },
- { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 82 },
- { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 12, 1, 82 },
- { 18, 1, 0, 0, 3, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 95 },
- { 18, 1, 0, 0, 2, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 95 },
- { 0, 17, 0, 220, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 95 },
- { 25, 1, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 95 },
- { 18, 13, 0, 0, 2, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 9 },
- { 18, 13, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 9 },
- { 18, 13, 0, 0, 3, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 9 },
- { 18, 13, 0, 0, 3, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 1, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 28, 13, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 10, 5, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 220, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 3, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 17, 13, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 0, 17, 0, 220, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 10, 5, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 2 },
- { 0, 17, 0, 220, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 220, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 27, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 28, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 29, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 11 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 11 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 11 },
- { 1, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 11 },
- { 0, 17, 0, 7, 5, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 11 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 11 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 11 },
- { 0, 17, 0, 220, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 11 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 2 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 11 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 11 },
- { 17, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 12 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 12 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 12 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 12 },
- { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 12 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 12 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 12 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 12 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 12 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 12 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 12 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 12 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 12 },
- { 5, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 12 },
- { 5, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 12 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 12 },
- { 27, 4, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 12 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 12 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 12 },
- { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 12 },
- { 0, 17, 0, 0, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 13 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 13 },
- { 1, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 13 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 13 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 13 },
- { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 13 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 13 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 13 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 13 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 13 },
- { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 13 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 14 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 14 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 14 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 14 },
- { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 14 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 14 },
- { 0, 17, 0, 0, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 14 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 14 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 14 },
- { 27, 4, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 14 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 14 },
- { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 14 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 15 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 15 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 15 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 15 },
- { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 15 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 15 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 15 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 15 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 15 },
- { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 15 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 15 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 15 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 15 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 15 },
- { 5, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 15 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 16 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 16 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 16 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 16 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 16 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 16 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 16 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 16 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 16 },
- { 3, 0, 0, 0, 0, 0, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 16 },
- { 5, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 16 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 16 },
- { 27, 4, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 16 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 17 },
- { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 17 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 17 },
- { 0, 17, 0, 7, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 17 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 0, 17, 0, 84, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 0, 17, 0, 91, 5, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 17 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 17 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 17 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 17 },
- { 25, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 17 },
- { 5, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 17 },
- { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 17 },
- { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 18 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 18 },
- { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 18 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 18 },
- { 0, 17, 0, 7, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 18 },
- { 0, 0, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 18 },
- { 0, 17, 0, 0, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 18 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 18 },
- { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 18 },
- { 1, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 18 },
- { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 19 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 19 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 19 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 19 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 19 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 19 },
- { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 19 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 19 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 19 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 19 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 19 },
- { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 19 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 19 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 15, 8, 1, 19 },
- { 29, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 19 },
- { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 19 },
- { 5, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 19 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 19 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 19 },
- { 5, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 19 },
- { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 19 },
- { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 20 },
- { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 20 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 20 },
- { 0, 17, 0, 9, 5, -1, 0, 4, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 20 },
- { 1, 0, 0, 0, 0, -1, 0, 4, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 20 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 20 },
- { 1, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 20 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 20 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 20 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 21 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 21 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 0, 44, 8, 3, 21 },
- { 0, 17, 0, 103, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 21 },
- { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 21 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 21 },
- { 0, 17, 0, 107, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 21 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 21 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 21 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 21 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 22 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 22 },
- { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 22 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 0, 44, 8, 3, 22 },
- { 0, 17, 0, 118, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 22 },
- { 0, 17, 0, 9, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 22 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 22 },
- { 0, 17, 0, 122, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 22 },
- { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 22 },
- { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 22 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 3, 22 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 22 },
- { 18, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 23 },
- { 29, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 7, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 2, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 7, 0, 3, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 0, 1, 23 },
- { 29, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 23 },
- { 0, 17, 0, 220, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 3, 0, 0, 0, 0, 0, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 2, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 3, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 4, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 5, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 6, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 7, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 8, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 3, 0, 0, 0, 0, 9, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 23 },
- { 5, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 23 },
- { 29, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 23 },
- { 0, 17, 0, 216, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 21, 10, 0, 0, 0, -1, 1, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 23 },
- { 22, 10, 0, 0, 0, -1, -1, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 23 },
- { 1, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 23 },
- { 18, 0, 0, 0, 0, -1, 0, 2, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 23 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 23 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 23 },
- { 0, 17, 0, 129, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 0, 17, 0, 130, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 0, 17, 0, 0, 5, -1, 0, 2, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 3, 23 },
- { 0, 17, 0, 132, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 0, 17, 0, 0, 5, -1, 0, 2, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 3, 23 },
- { 0, 17, 0, 0, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 1, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 21, 4, 1, 23 },
- { 0, 17, 0, 230, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 0, 17, 0, 9, 5, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 23 },
- { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 23 },
- { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 23 },
- { 0, 17, 0, 220, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 23 },
- { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 23 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 23 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 7, 0, 1, 23 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 24 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 24 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 24 },
- { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 4, 44, 4, 1, 24 },
- { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 4, 44, 4, 1, 24 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 44, 4, 1, 24 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 0, 17, 0, 7, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 0, 17, 0, 9, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 0, 17, 0, 9, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 44, 4, 1, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 2, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 3, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 4, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 5, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 6, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 7, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 8, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 9, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 24 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 24 },
- { 0, 17, 0, 220, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 4, 44, 4, 1, 24 },
- { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 0, 1, 24 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 7264}, {0, 0}, {0, 0}, {0, 7264} } }, 0, 10, 15, 7, 3, 25 },
- { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 7264}, {0, 0}, {0, 0}, {0, 7264} } }, 0, 10, 15, 7, 3, 25 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 3008}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 25 },
- { 15, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 3008}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 25 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 3008}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 25 },
- { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 25 },
- { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 3008}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 25 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 9, 10, 31, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 9, 10, 31, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 9, 10, 31, 8, 2, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 32, 8, 2, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 32, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 32, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 32, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 11, 10, 33, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 11, 10, 33, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 11, 10, 33, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 27 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 27 },
- { 0, 17, 0, 230, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 27 },
- { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 27 },
- { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 27 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 12, 1, 27 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 2, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 3, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 4, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 5, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 6, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 7, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 8, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, 9, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 5, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 27 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 45}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 47}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 49}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 51}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 53}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 55}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 57}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 59}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 61}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 63}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 65}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 67}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 69}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 71}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 73}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 75}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 77}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 79}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 81}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 83}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 85}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 87}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 89}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 91}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 93}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 95}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 97}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 99}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 101}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 103}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 105}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 107}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 109}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 111}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 113}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 115}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 117}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 119}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 121}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 123}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 125}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 127}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 129}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 131}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 133}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 135}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 137}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 139}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 141}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 143}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 145}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 147}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 149}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 151}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 153}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 155}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 157}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 159}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 161}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 163}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 165}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 167}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 169}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 171}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 173}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 175}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 177}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 179}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 181}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 183}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 185}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 187}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 189}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 191}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 193}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 195}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 197}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 199}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 201}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 1, 203}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 8}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 8}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, -8}, {0, -8}, {0, -8} } }, 0, 10, 15, 6, 3, 28 },
- { 20, 10, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 29 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 29 },
- { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 29 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 12, 1, 29 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 29 },
- { 6, 9, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 18, 21, 5, 0, 30 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 30 },
- { 21, 10, 0, 0, 0, -1, 1, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 30 },
- { 22, 10, 0, 0, 0, -1, -1, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 30 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 31 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 4, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 31 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 31 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 42 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 42 },
- { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 42 },
- { 0, 17, 0, 9, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 42 },
- { 1, 0, 0, 9, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 42 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 43 },
- { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 43 },
- { 1, 0, 0, 9, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 43 },
- { 25, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 44 },
- { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 44 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 45 },
- { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 45 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 32 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 2, 32 },
- { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 44, 4, 1, 32 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 32 },
- { 0, 17, 0, 9, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 32 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 32 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 0, 1, 32 },
- { 17, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 32 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 32 },
- { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 32 },
- { 27, 4, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 32 },
- { 0, 17, 0, 230, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 32 },
- { 3, 0, 0, 0, 0, 0, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 2, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 3, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 4, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 5, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 6, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 7, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 8, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 3, 0, 0, 0, 0, 9, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 32 },
- { 5, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 32 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 33 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 11, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 33 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 33 },
- { 25, 10, 0, 0, 2, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 33 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 11, 1, 33 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 33 },
- { 25, 10, 0, 0, 1, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 33 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 2, 33 },
- { 10, 18, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 7, 4, 2, 33 },
- { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 2, 33 },
- { 3, 0, 0, 0, 0, 0, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 2, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 3, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 4, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 5, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 6, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 7, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 8, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 3, 0, 0, 0, 0, 9, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 33 },
- { 18, 0, 0, 0, 2, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 33 },
- { 17, 0, 0, 0, 2, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 33 },
- { 18, 0, 0, 0, 2, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 33 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 33 },
- { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 33 },
- { 0, 17, 0, 228, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 33 },
- { 18, 0, 0, 0, 2, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 33 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 47 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 47 },
- { 0, 17, 0, 0, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 47 },
- { 1, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 47 },
- { 0, 17, 0, 222, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 47 },
- { 0, 17, 0, 230, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 47 },
- { 0, 17, 0, 220, 5, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 47 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 47 },
- { 25, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 47 },
- { 3, 0, 0, 0, 0, 0, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 2, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 3, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 4, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 5, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 6, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 7, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 8, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 3, 0, 0, 0, 0, 9, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 47 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 48 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 56 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 56 },
- { 3, 0, 0, 0, 0, 0, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 2, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 3, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 4, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 5, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 6, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 7, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 8, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 3, 0, 0, 0, 0, 9, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 5, 0, 0, 0, 0, 1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 56 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 0, 1, 56 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 32 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 55 },
- { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 55 },
- { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 55 },
- { 1, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 55 },
- { 0, 17, 0, 0, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 55 },
- { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 55 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 78 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 44, 4, 1, 78 },
- { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 78 },
- { 0, 17, 0, 9, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 78 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 4, 44, 4, 1, 78 },
- { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 78 },
- { 0, 17, 0, 220, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 78 },
- { 3, 0, 0, 0, 0, 0, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 2, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 3, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 4, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 5, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 6, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 7, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 8, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 3, 0, 0, 0, 0, 9, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 78 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 0, 1, 78 },
- { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 78 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 12, 1, 78 },
- { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 2, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 0, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 62 },
- { 1, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 62 },
- { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 62 },
- { 18, 0, 0, 0, 0, -1, 0, 9, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 62 },
- { 0, 17, 0, 7, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 62 },
- { 1, 0, 0, 0, 0, -1, 0, 9, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 62 },
- { 1, 0, 0, 0, 0, -1, 0, 9, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 62 },
- { 1, 0, 0, 0, 0, -1, 0, 9, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 62 },
- { 1, 0, 0, 9, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 41, 4, 1, 62 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 62 },
- { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 62 },
- { 3, 0, 0, 0, 0, 0, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 2, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 3, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 4, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 5, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 6, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 7, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 8, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 3, 0, 0, 0, 0, 9, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 62 },
- { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 62 },
- { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 62 },
- { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 62 },
- { 29, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 62 },
- { 0, 17, 0, 230, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 62 },
- { 0, 17, 0, 220, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 62 },
- { 25, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 62 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 67 },
- { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 67 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 67 },
- { 1, 0, 0, 9, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 67 },
- { 0, 17, 0, 9, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 67 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 67 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 67 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 67 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 93 },
- { 0, 17, 0, 7, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 93 },
- { 1, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 93 },
- { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 93 },
- { 1, 0, 0, 9, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 42, 4, 1, 93 },
- { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 93 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 68 },
- { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 68 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 68 },
- { 0, 17, 0, 7, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 68 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 68 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 68 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 69 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 69 },
- { 17, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 69 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 69 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -6254}, {0, -6254}, {0, -6222} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -6253}, {0, -6253}, {0, -6221} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -6244}, {0, -6244}, {0, -6212} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -6242}, {0, -6242}, {0, -6210} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -6243}, {0, -6243}, {0, -6211} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -6236}, {0, -6236}, {0, -6204} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -6181}, {0, -6181}, {0, -6180} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {1, 205}, {1, 205}, {1, 727} } }, 0, 10, 15, 6, 3, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 14, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, -3008}, {0, 0}, {0, 0}, {0, -3008} } }, 0, 10, 15, 8, 3, 25 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 67 },
- { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 0, 17, 0, 1, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 1, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 5 },
- { 17, 0, 0, 0, 0, -1, 0, 7, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 7, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 5 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {1, 207}, {1, 207}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 3814}, {0, 3814}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {1, 209}, {1, 209}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 234, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 214, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 202, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 232, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 228, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 218, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 233, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 522}, {1, 522}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 525}, {1, 525}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 528}, {1, 528}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 531}, {1, 531}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 534}, {1, 534}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 2, 3, 81, { { { 0, 0}, {0, -59}, {0, -59}, {0, -58} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, -7615}, {0, 0}, {0, 0}, {0, -7615} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 8}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {0, 0}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 537}, {1, 537}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 540}, {1, 540}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 544}, {1, 544}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 548}, {1, 548}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 74}, {0, 74}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 74}, {0, 74}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 86}, {0, 86}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 86}, {0, 86}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 100}, {0, 100}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 100}, {0, 100}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 128}, {0, 128}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 128}, {0, 128}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 112}, {0, 112}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 112}, {0, 112}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 126}, {0, 126}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 126}, {0, 126}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 586}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 589}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 592}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 595}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 598}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 601}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 604}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 607}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 586}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 589}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 592}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 595}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 598}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 601}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 604}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 607}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 610}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 613}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 616}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 619}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 622}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 625}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 628}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 631}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 610}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 613}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 616}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 619}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 622}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 625}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 628}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 631}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 634}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 637}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 640}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 643}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 646}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 649}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 652}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 655}, {0, 8}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 634}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 637}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 640}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 643}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 646}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 649}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 652}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -8}, {1, 655}, {0, 0}, {0, -8} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 670}, {1, 667}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 658}, {0, 9}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 676}, {1, 673}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 552}, {1, 552}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 707}, {1, 703}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -74}, {0, 0}, {0, 0}, {0, -74} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, -74}, {0, 0}, {0, 0}, {0, -74} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -9}, {1, 658}, {0, 0}, {0, -9} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, -7205}, {0, -7205}, {0, -7173} } }, 0, 10, 15, 6, 3, 4 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 81, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 682}, {1, 679}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 661}, {0, 9}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 688}, {1, 685}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 555}, {1, 555}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 715}, {1, 711}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -86}, {0, 0}, {0, 0}, {0, -86} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, -86}, {0, 0}, {0, 0}, {0, -86} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -9}, {1, 661}, {0, 0}, {0, -9} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 558}, {1, 558}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {1, 511}, {1, 511}, {0, -7235} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 562}, {1, 562}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 565}, {1, 565}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -100}, {0, 0}, {0, 0}, {0, -100} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, -100}, {0, 0}, {0, 0}, {0, -100} } }, 0, 10, 15, 7, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 569}, {1, 569}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {1, 515}, {1, 515}, {0, -7219} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 573}, {1, 573}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 7}, {0, 7}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 576}, {1, 576}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 579}, {1, 579}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -112}, {0, 0}, {0, 0}, {0, -112} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, -112}, {0, 0}, {0, 0}, {0, -112} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -7}, {0, 0}, {0, 0}, {0, -7} } }, 0, 10, 15, 7, 3, 4 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 694}, {1, 691}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 664}, {0, 9}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 700}, {1, 697}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 583}, {1, 583}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {1, 723}, {1, 719}, {0, 0} } }, 0, 10, 15, 6, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -128}, {0, 0}, {0, 0}, {0, -128} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, -128}, {0, 0}, {0, 0}, {0, -128} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -126}, {0, 0}, {0, 0}, {0, -126} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, -126}, {0, 0}, {0, 0}, {0, -126} } }, 0, 10, 15, 7, 3, 4 },
- { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, -9}, {1, 664}, {0, 0}, {0, -9} } }, 0, 10, 15, 7, 3, 4 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 3, 4 },
- { 6, 9, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 18, 21, 5, 3, 2 },
- { 6, 9, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 18, 21, 5, 3, 2 },
- { 6, 9, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 7, 5, 3, 2 },
- { 10, 18, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 0, 26, 4, 2, 2 },
- { 10, 18, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 4, 1 },
- { 10, 18, 16, 0, 1, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 5, 5, 43, 4, 4, 1 },
- { 10, 0, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 1, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 7, 0, 3, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 11, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 25, 11, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 23, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 13, 3, 13, 1, 2 },
- { 24, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 13, 3, 13, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 23, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 23, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 24, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 13, 18, 10, 0, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 18, 0, 0, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 21, 0, 1, 2 },
- { 7, 9, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 3, 49, 3, 0, 2 },
- { 8, 7, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 3, 49, 3, 0, 2 },
- { 10, 11, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 14, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 16, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 12, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 15, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 6, 6, 0, 0, 0, -1, 0, 4, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 17, 7, 5, 3, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 23, 10, 0, 0, 0, -1, 1, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 24, 10, 0, 0, 0, -1, -1, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 25, 10, 1, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 8, 12, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 12, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 19, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 17, 15, 0, 1, 2 },
- { 26, 6, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 11, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 12, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 12, 3, 2 },
- { 25, 10, 1, 0, 0, -1, 0, 4, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 8, 12, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 19, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 17, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 6, 9, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 18, 21, 5, 3, 2 },
- { 10, 18, 0, 0, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 28, 4, 2, 2 },
- { 10, 18, 0, 0, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 15, 4, 2, 2 },
- { 10, 18, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 15, 4, 2, 2 },
- { 13, 18, 0, 0, 0, -1, 0, 0, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 0, 15, 0, 0, 0 },
- { 10, 19, 0, 0, 0, -1, 0, 15, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 20, 0, 0, 0, -1, 0, 15, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 21, 0, 0, 0, -1, 0, 15, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 22, 0, 0, 0, -1, 0, 15, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 18, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 2, 2 },
- { 5, 2, 0, 0, 0, 0, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 5, 2, 0, 0, 0, 4, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 5, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 6, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 7, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 8, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 9, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 26, 3, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 12, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 3, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 2, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 3, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 14, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 13, 4, 0, 0, 0, -1, 0, 0, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 0, 0 },
- { 0, 17, 0, 1, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 2, 17, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 2, 17, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 2, 17, 16, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 2, 17, 0, 0, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 1, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 1, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 85, { { { 0, -7517}, {0, 0}, {0, 0}, {0, -7517} } }, 0, 10, 15, 7, 3, 4 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, { { { 1, 211}, {0, 0}, {0, 0}, {1, 211} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 0, 85, { { { 1, 213}, {0, 0}, {0, 0}, {1, 213} } }, 0, 10, 15, 7, 3, 3 },
- { 29, 4, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 28}, {0, 0}, {0, 0}, {0, 28} } }, 0, 10, 15, 7, 3, 3 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 2 },
- { 15, 0, 1, 0, 0, -1, 0, 4, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 10, 15, 6, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, -28}, {0, -28}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 11, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 4, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 16}, {0, 0}, {0, 0}, {0, 16} } }, 0, 10, 15, 7, 3, 3 },
- { 4, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 16}, {0, 0}, {0, 0}, {0, 16} } }, 0, 10, 15, 7, 3, 3 },
- { 4, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, -16}, {0, -16}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 4, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, -16}, {0, -16}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 4, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 3 },
- { 4, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 3 },
- { 5, 10, 0, 0, 0, -1, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 1, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 3, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 3, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 3, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -3, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -3, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -3, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 3, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 26, 4, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2016, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2527, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1923, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1914, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1918, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2250, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 138, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 7, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -7, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 0, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 1, 0, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 1, 0, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 1, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1824, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2104, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2108, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2106, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1316, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -138, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 18, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 8, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 7, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -8, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -7, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 2, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 3, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 4, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 5, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 6, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 7, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 8, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, 9, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 2, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 3, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 4, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 5, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 6, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 7, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 8, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 9, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 26}, {0, 0}, {0, 0}, {0, 26} } }, 0, 10, 15, 7, 3, 2 },
- { 29, 0, 1, 0, 0, -1, 0, 1, 0, 80, { { { 0, 26}, {0, 0}, {0, 0}, {0, 26} } }, 14, 10, 15, 7, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 0, 80, { { { 0, 0}, {0, -26}, {0, -26}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 5, 10, 0, 0, 0, 0, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 1, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 2, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 3, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 4, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 5, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 6, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 7, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 8, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 9, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 0, 0, 7, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 1, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 26, 10, 3, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 7, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 9, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 8, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 8, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 7, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 11, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 9, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 11, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 9, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 5, 10, 0, 0, 0, 1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 2, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 3, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 4, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 5, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 6, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 7, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 8, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 9, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 2, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 3, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 4, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 5, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 6, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 7, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 8, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, 9, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 2, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -2, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1316, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 6, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 6, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 10, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 10, 4, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 54 },
- { 21, 10, 0, 0, 0, -1, 3, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, 1, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 21, 10, 0, 0, 0, -1, -1, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -3, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1914, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1918, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1923, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -1824, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -2016, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 6, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, -2104, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -2106, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -2108, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 26, 10, 0, 0, 0, -1, -2250, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 10, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, -2527, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 48}, {0, 0}, {0, 0}, {0, 48} } }, 0, 10, 15, 7, 3, 57 },
- { 14, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 48}, {0, 0}, {0, 0}, {0, 48} } }, 0, 10, 15, 7, 3, 57 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, -48}, {0, -48}, {0, 0} } }, 0, 10, 15, 6, 1, 57 },
- { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, -48}, {0, -48}, {0, 0} } }, 0, 10, 15, 6, 1, 57 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 1, 215}, {0, 0}, {0, 0}, {1, 215} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, -3814}, {0, 0}, {0, 0}, {0, -3814} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 1, 217}, {0, 0}, {0, 0}, {1, 217} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {1, 219}, {1, 219}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {1, 221}, {1, 221}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 1, 223}, {0, 0}, {0, 0}, {1, 223} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 1, 225}, {0, 0}, {0, 0}, {1, 225} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 1, 227}, {0, 0}, {0, 0}, {1, 227} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 1, 229}, {0, 0}, {0, 0}, {1, 229} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 10, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 1, 231}, {0, 0}, {0, 0}, {1, 231} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 1, 233}, {0, 0}, {0, 0}, {1, 233} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 46 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 46 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 46 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 46 },
- { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 46 },
- { 15, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 46 },
- { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 46 },
- { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 46 },
- { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 46 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 46 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 46 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 46 },
- { 5, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 46 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 0, 1, 46 },
- { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, -7264}, {0, -7264}, {0, 0} } }, 0, 10, 15, 6, 1, 25 },
- { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, -7264}, {0, -7264}, {0, 0} } }, 0, 10, 15, 6, 1, 25 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 58 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 58 },
- { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 58 },
- { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 58 },
- { 0, 17, 0, 9, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 58 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 23, 10, 0, 0, 0, -1, 1, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 24, 10, 0, 0, 0, -1, -1, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 23, 10, 0, 0, 0, -1, 1, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 24, 10, 0, 0, 0, -1, -1, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 2 },
- { 17, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 25, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 2, 13, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 37 },
- { 29, 10, 0, 0, 0, -1, 0, 4, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 37 },
- { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 0, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 26, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 0, 2 },
- { 6, 9, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 18, 21, 5, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 11, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 12, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 8, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 2 },
- { 4, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 1, 2 },
- { 22, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 0, 17, 0, 218, 5, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 228, 5, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 232, 5, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 222, 5, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 1, 0, 0, 224, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 26 },
- { 20, 10, 1, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 8, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 27, 8, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 4, 0, 0, 0, 0, -1, 0, 4, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 37 },
- { 17, 0, 0, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 8, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 8, 8, 1, 2 },
- { 25, 10, 1, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 8, 1, 34 },
- { 0, 17, 0, 8, 5, -1, 0, 1, 5, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 0, 3, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 8, 1, 34 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 34 },
- { 20, 10, 0, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 0, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 8, 1, 35 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 0, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 1, 35 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 5, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 8, 3, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 36 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 36 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 36 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 36 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 3, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 2, 26 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 5, 0, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 36 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 36 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 36 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 10, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 27, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 1, 35 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 26 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 26 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 5, 0, 0, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 7, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 6, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 26 },
- { 29, 0, 1, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 0, 3, 35 },
- { 29, 0, 0, 0, 0, -1, 0, 22, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 0, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 38 },
- { 17, 0, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 8, 8, 1, 38 },
- { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 38 },
- { 29, 10, 0, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 38 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 83 },
- { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 83 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 83 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 83 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 70 },
- { 17, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 70 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 70 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 70 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 70 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 70 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 5 },
- { 2, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 5 },
- { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 5 },
- { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 5 },
- { 17, 10, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 5 },
- { 17, 0, 0, 0, 0, -1, 0, 16, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 5 },
- { 0, 17, 0, 230, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 5 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 84 },
- { 4, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 84 },
- { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 84 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 84 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 84 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 84 },
- { 28, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 17, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 1, 235}, {0, 0}, {0, 0}, {1, 235} } }, 0, 10, 15, 7, 3, 3 },
- { 28, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 1, 237}, {0, 0}, {0, 0}, {1, 237} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 48}, {0, 48}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 1, 239}, {0, 0}, {0, 0}, {1, 239} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 1, 241}, {0, 0}, {0, 0}, {1, 241} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 1, 243}, {0, 0}, {0, 0}, {1, 243} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 1, 245}, {0, 0}, {0, 0}, {1, 245} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 1, 247}, {0, 0}, {0, 0}, {1, 247} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 1, 249}, {0, 0}, {0, 0}, {1, 249} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 1, 251}, {0, 0}, {0, 0}, {1, 251} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 1, 253}, {0, 0}, {0, 0}, {1, 253} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 928}, {0, 0}, {0, 0}, {0, 928} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, -48}, {0, 0}, {0, 0}, {0, -48} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 1, 255}, {0, 0}, {0, 0}, {1, 255} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 1, 257}, {0, 0}, {0, 0}, {1, 257} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 1, 259}, {0, 0}, {0, 0}, {1, 259} } }, 0, 10, 15, 7, 3, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 1}, {0, 0}, {0, 0}, {0, 1} } }, 0, 10, 15, 7, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, -1}, {0, -1}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 1, 261}, {0, 0}, {0, 0}, {1, 261} } }, 0, 10, 15, 7, 3, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 24, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 13, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 3 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 59 },
- { 0, 17, 0, 0, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 59 },
- { 0, 17, 0, 9, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 59 },
- { 1, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 59 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 59 },
- { 0, 17, 0, 9, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 59 },
- { 5, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 4, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 18, 0, 0, 0, 2, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 65 },
- { 18, 0, 0, 0, 4, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 65 },
- { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 65 },
- { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 65 },
- { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 1, 65 },
- { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 71 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 71 },
- { 0, 17, 0, 9, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 71 },
- { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 71 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 71 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 71 },
- { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 11 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 11 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 11 },
- { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 11 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 72 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 72 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 72 },
- { 0, 17, 0, 220, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 72 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 72 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 73 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 73 },
- { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 73 },
- { 1, 0, 0, 9, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 73 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 73 },
- { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 85 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 85 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 85 },
- { 0, 17, 0, 7, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 85 },
- { 1, 0, 0, 9, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 41, 4, 1, 85 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 85 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 85 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 85 },
- { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 21, 8, 1, 2 },
- { 3, 0, 0, 0, 0, 0, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 2, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 3, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 4, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 5, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 6, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 7, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 8, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 3, 0, 0, 0, 0, 9, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 85 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 24 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 24 },
- { 17, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 24 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 77 },
- { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 77 },
- { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 77 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 21, 8, 1, 77 },
- { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 77 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 77 },
- { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 77 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 24 },
- { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 24 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 0, 1, 24 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 4, 44, 4, 1, 24 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 79 },
- { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 79 },
- { 0, 17, 0, 220, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 79 },
- { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 79 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 0, 1, 79 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 86 },
- { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 86 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 86 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 86 },
- { 17, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 86 },
- { 0, 17, 0, 9, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 86 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 27 },
- { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, -928}, {0, -928}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 28, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 0, 1, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 16, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 4 },
- { 15, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 28, 10, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 263}, {1, 263}, {1, 263} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 265}, {1, 265}, {1, 265} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 267}, {1, 267}, {1, 267} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 269}, {1, 269}, {1, 269} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 271}, {1, 271}, {1, 271} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 273}, {1, 273}, {1, 273} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 275}, {1, 275}, {1, 275} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 277}, {1, 277}, {1, 277} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 279}, {1, 279}, {1, 279} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 281}, {1, 281}, {1, 281} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 283}, {1, 283}, {1, 283} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 285}, {1, 285}, {1, 285} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 287}, {1, 287}, {1, 287} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 289}, {1, 289}, {1, 289} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 291}, {1, 291}, {1, 291} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 293}, {1, 293}, {1, 293} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 295}, {1, 295}, {1, 295} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 297}, {1, 297}, {1, 297} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 299}, {1, 299}, {1, 299} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 301}, {1, 301}, {1, 301} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 303}, {1, 303}, {1, 303} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 305}, {1, 305}, {1, 305} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 307}, {1, 307}, {1, 307} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 309}, {1, 309}, {1, 309} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 311}, {1, 311}, {1, 311} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 313}, {1, 313}, {1, 313} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 315}, {1, 315}, {1, 315} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 317}, {1, 317}, {1, 317} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 319}, {1, 319}, {1, 319} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 321}, {1, 321}, {1, 321} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 323}, {1, 323}, {1, 323} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 325}, {1, 325}, {1, 325} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 327}, {1, 327}, {1, 327} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 329}, {1, 329}, {1, 329} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 331}, {1, 331}, {1, 331} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 333}, {1, 333}, {1, 333} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 335}, {1, 335}, {1, 335} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 337}, {1, 337}, {1, 337} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 339}, {1, 339}, {1, 339} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 341}, {1, 341}, {1, 341} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 343}, {1, 343}, {1, 343} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 345}, {1, 345}, {1, 345} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 347}, {1, 347}, {1, 347} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 349}, {1, 349}, {1, 349} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 351}, {1, 351}, {1, 351} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 353}, {1, 353}, {1, 353} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 355}, {1, 355}, {1, 355} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 357}, {1, 357}, {1, 357} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 359}, {1, 359}, {1, 359} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 361}, {1, 361}, {1, 361} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 363}, {1, 363}, {1, 363} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 365}, {1, 365}, {1, 365} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 367}, {1, 367}, {1, 367} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 369}, {1, 369}, {1, 369} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 371}, {1, 371}, {1, 371} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 373}, {1, 373}, {1, 373} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 375}, {1, 375}, {1, 375} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 377}, {1, 377}, {1, 377} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 379}, {1, 379}, {1, 379} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 381}, {1, 381}, {1, 381} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 383}, {1, 383}, {1, 383} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 385}, {1, 385}, {1, 385} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 387}, {1, 387}, {1, 387} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 389}, {1, 389}, {1, 389} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 391}, {1, 391}, {1, 391} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 393}, {1, 393}, {1, 393} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 395}, {1, 395}, {1, 395} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 397}, {1, 397}, {1, 397} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 399}, {1, 399}, {1, 399} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 401}, {1, 401}, {1, 401} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 403}, {1, 403}, {1, 403} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 405}, {1, 405}, {1, 405} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 407}, {1, 407}, {1, 407} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 409}, {1, 409}, {1, 409} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 411}, {1, 411}, {1, 411} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 413}, {1, 413}, {1, 413} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 415}, {1, 415}, {1, 415} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 417}, {1, 417}, {1, 417} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 419}, {1, 419}, {1, 419} } }, 0, 10, 15, 6, 3, 28 },
- { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {1, 421}, {1, 421}, {1, 421} } }, 0, 10, 15, 6, 3, 28 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 86 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 86 },
- { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 86 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 86 },
- { 0, 17, 0, 9, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 86 },
- { 3, 0, 0, 0, 0, 0, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 2, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 3, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 4, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 5, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 6, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 7, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 8, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 3, 0, 0, 0, 0, 9, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 86 },
- { 18, 0, 0, 0, 0, -1, 0, 2, 5, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 12, 10, 29, 8, 1, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 2, 5, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 13, 10, 30, 8, 1, 26 },
- { 11, 0, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 45, 0, 0, 0 },
- { 12, 0, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 6, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 37 },
- { 13, 0, 0, 0, 0, -1, 0, 0, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 0, 0 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 37 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 435}, {1, 432}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 441}, {1, 438}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 447}, {1, 444}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 454}, {1, 450}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 462}, {1, 458}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 469}, {1, 466}, {0, 1} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 469}, {1, 466}, {0, 0} } }, 0, 10, 15, 6, 3, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 481}, {1, 478}, {0, 0} } }, 0, 10, 15, 6, 3, 6 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 487}, {1, 484}, {0, 0} } }, 0, 10, 15, 6, 3, 6 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 493}, {1, 490}, {0, 0} } }, 0, 10, 15, 6, 3, 6 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 499}, {1, 496}, {0, 0} } }, 0, 10, 15, 6, 3, 6 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {1, 505}, {1, 502}, {0, 0} } }, 0, 10, 15, 6, 3, 6 },
- { 18, 1, 0, 0, 0, -1, 0, 4, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 9, 16, 8, 3, 7 },
- { 0, 17, 0, 26, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 7 },
- { 18, 1, 0, 0, 0, -1, 0, 1, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 9, 16, 8, 3, 7 },
- { 18, 1, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 9, 16, 8, 3, 7 },
- { 26, 3, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 7 },
- { 18, 13, 0, 0, 0, -1, 0, 1, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 8 },
- { 28, 13, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 22, 10, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 13, 18, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 },
- { 27, 13, 0, 0, 0, -1, 0, 6, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 8 },
- { 0, 17, 0, 0, 5, -1, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 2, 1 },
- { 0, 17, 16, 0, 5, -1, 0, 6, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 2, 1 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 11, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 12, 0, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 8, 11, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 11, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 3, 2 },
- { 21, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 18, 0, 0, 2 },
- { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 5 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 0, 2 },
- { 20, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 11, 3, 2 },
- { 19, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 17, 17, 0, 3, 2 },
- { 21, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 6, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 21, 10, 0, 0, 0, -1, 0, 7, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, 0, 7, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 1, 11, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 11, 3, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 13, 1, 10, 0, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 8, 11, 3, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 8, 11, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 3, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 26, 3, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 20, 3, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 11, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 1, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, -1, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 3, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 18, 13, 0, 0, 0, -1, 0, 6, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 10, 18, 0, 0, 5, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 28, 4, 2, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 12, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 3, 2 },
- { 25, 4, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 13, 17, 0, 3, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 26, 3, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 1, 11, 3, 2 },
- { 20, 3, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 11, 3, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 13, 1, 10, 3, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 2, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 3, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 4, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 5, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 6, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 7, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 8, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 9, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 17, 9, 3, 2 },
- { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 14, 8, 11, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 15, 8, 11, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 2, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, -2, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 17, 7, 3, 3 },
- { 21, 10, 0, 0, 0, -1, 2, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, -2, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 28, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 19, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 17, 17, 0, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 17, 6, 3, 3 },
- { 21, 10, 0, 0, 0, -1, 1, 6, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 6, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 12, 3, 2 },
- { 21, 10, 0, 0, 0, -1, 1, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 13, 3, 2 },
- { 22, 10, 0, 0, 0, -1, -1, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 13, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 1, 11, 3, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 0, 3, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 8, 3, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 3, 35 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 3, 2 },
- { 17, 0, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 8, 4, 3, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 2, 26 },
- { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 3, 26 },
- { 27, 4, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 1, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 1, 2, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 10, 10, 0, 0, 5, -1, 0, 4, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 3, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 35, 0, 0, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 13, 18, 0, 0, 0, -1, 0, 1, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 49 },
- { 25, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 25, 10, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 2 },
- { 5, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 4, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 4 },
- { 5, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 4 },
- { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 4 },
- { 5, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 4 },
- { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 4 },
- { 29, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 4 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 74 },
- { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 75 },
- { 5, 2, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 18, 0, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 39 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 39 },
- { 5, 0, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 39 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 39 },
- { 18, 0, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 40 },
- { 4, 0, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 40 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 120 },
- { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 120 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 50 },
- { 25, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 50 },
- { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 60 },
- { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 60 },
- { 4, 0, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 60 },
- { 14, 0, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 40}, {0, 0}, {0, 0}, {0, 40} } }, 0, 10, 15, 7, 3, 41 },
- { 14, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 40}, {0, 0}, {0, 0}, {0, 40} } }, 0, 10, 15, 7, 3, 41 },
- { 15, 0, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, -40}, {0, -40}, {0, 0} } }, 0, 10, 15, 6, 1, 41 },
- { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, -40}, {0, -40}, {0, 0} } }, 0, 10, 15, 6, 1, 41 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 51 },
- { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 52 },
- { 3, 0, 0, 0, 0, 0, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 2, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 3, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 4, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 5, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 6, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 7, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 8, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 3, 0, 0, 0, 0, 9, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 52 },
- { 14, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 40}, {0, 0}, {0, 0}, {0, 40} } }, 0, 10, 15, 7, 3, 136 },
- { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -40}, {0, -40}, {0, 0} } }, 0, 10, 15, 6, 1, 136 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 106 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 103 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 103 },
- { 14, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 39}, {0, 0}, {0, 0}, {0, 39} } }, 0, 10, 15, 7, 3, 161 },
- { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, -39}, {0, -39}, {0, 0} } }, 0, 10, 15, 6, 1, 161 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 169 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 169 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 110 },
- { 17, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 17, 0, 0, 0, 0, -1, 0, 24, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 3 },
- { 18, 1, 0, 0, 0, -1, 0, 7, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 53 },
- { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 87 },
- { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 87 },
- { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 87 },
- { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 118 },
- { 29, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 118 },
- { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 118 },
- { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 117 },
- { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 117 },
- { 18, 1, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 128 },
- { 5, 1, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 128 },
- { 18, 1, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 64 },
- { 5, 1, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 64 },
- { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 64 },
- { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 64 },
- { 18, 1, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 76 },
- { 25, 1, 0, 0, 0, -1, 0, 10, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 76 },
- { 18, 1, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 98 },
- { 18, 1, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 97 },
- { 5, 1, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 97 },
- { 18, 1, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 61 },
- { 0, 17, 0, 0, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 61 },
- { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 61 },
- { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 61 },
- { 18, 1, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 61 },
- { 0, 17, 0, 1, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 61 },
- { 0, 17, 0, 9, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 61 },
- { 5, 1, 0, 0, 0, 1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 61 },
- { 5, 1, 0, 0, 0, 2, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 61 },
- { 5, 1, 0, 0, 0, 3, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 61 },
- { 5, 1, 0, 0, 0, 4, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 61 },
- { 5, 1, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 61 },
- { 5, 1, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 61 },
- { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 61 },
- { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 61 },
- { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 61 },
- { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 88 },
- { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 88 },
- { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 88 },
- { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 116 },
- { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 116 },
- { 18, 1, 0, 0, 2, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 112 },
- { 18, 1, 0, 0, 3, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 112 },
- { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 112 },
- { 29, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 112 },
- { 18, 1, 0, 0, 4, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 112 },
- { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 112 },
- { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 112 },
- { 5, 1, 0, 0, 2, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 112 },
- { 5, 1, 0, 0, 3, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 112 },
- { 25, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 112 },
- { 25, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 18, 0, 1, 112 },
- { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 80 },
- { 25, 10, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 80 },
- { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 89 },
- { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 89 },
- { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 90 },
- { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 90 },
- { 18, 1, 0, 0, 2, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 121 },
- { 18, 1, 0, 0, 3, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 121 },
- { 25, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 121 },
- { 5, 1, 0, 0, 3, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 121 },
- { 5, 1, 0, 0, 2, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 121 },
- { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 121 },
- { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 91 },
- { 14, 1, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 64}, {0, 0}, {0, 0}, {0, 64} } }, 0, 10, 15, 7, 3, 130 },
- { 15, 1, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, -64}, {0, -64}, {0, 0} } }, 0, 10, 15, 6, 1, 130 },
- { 5, 1, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 130 },
- { 18, 13, 0, 0, 4, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 144 },
- { 18, 13, 0, 0, 2, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 144 },
- { 18, 13, 0, 0, 3, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 144 },
- { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 144 },
- { 3, 5, 0, 0, 0, 0, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 2, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 3, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 4, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 5, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 6, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 7, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 8, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 9, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 144 },
- { 3, 5, 0, 0, 0, 0, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 2, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 3, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 4, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 5, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 6, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 7, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 8, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 3, 5, 0, 0, 0, 9, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 164 },
- { 18, 1, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 164 },
- { 17, 1, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 164 },
- { 14, 1, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 164 },
- { 0, 17, 0, 230, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 164 },
- { 20, 10, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 164 },
- { 15, 1, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 164 },
- { 26, 1, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 164 },
- { 5, 5, 0, 0, 0, 1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 2, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 3, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 4, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 5, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 6, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 7, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 8, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, 9, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 5, 5, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 18, 1, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 156 },
- { 0, 17, 0, 230, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 156 },
- { 20, 1, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 156 },
- { 18, 13, 0, 0, 3, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 18, 13, 0, 0, 2, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 8 },
- { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 0, 17, 0, 220, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 8 },
- { 18, 1, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 147 },
- { 5, 1, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 147 },
- { 18, 13, 0, 0, 2, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 148 },
- { 18, 13, 0, 0, 3, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 148 },
- { 18, 13, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 148 },
- { 0, 17, 0, 220, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 148 },
- { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 148 },
- { 5, 13, 0, 0, 2, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 148 },
- { 5, 13, 0, 0, 3, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 148 },
- { 25, 13, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 12, 1, 148 },
- { 18, 1, 0, 0, 2, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 158 },
- { 18, 1, 0, 0, 3, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 158 },
- { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 158 },
- { 0, 17, 0, 220, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 158 },
- { 25, 1, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 12, 1, 158 },
- { 18, 1, 0, 0, 2, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 153 },
- { 18, 1, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 153 },
- { 18, 1, 0, 0, 3, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 153 },
- { 5, 1, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 153 },
- { 5, 1, 0, 0, 3, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 153 },
- { 5, 1, 0, 0, 2, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 153 },
- { 5, 1, 0, 0, 4, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 153 },
- { 18, 1, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 149 },
- { 1, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 94 },
- { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 94 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 39, 8, 1, 94 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 94 },
- { 0, 17, 0, 9, 5, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 41, 4, 1, 94 },
- { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 94 },
- { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 2, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 3, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 4, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 5, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 6, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 7, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 8, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, 9, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 5, 10, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 94 },
- { 3, 0, 0, 0, 0, 0, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 2, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 3, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 4, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 5, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 6, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 7, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 8, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 3, 0, 0, 0, 0, 9, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 94 },
- { 0, 17, 0, 9, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 94 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 94 },
- { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 94 },
- { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 94 },
- { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 92 },
- { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 92 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 92 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 92 },
- { 0, 17, 0, 9, 5, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 92 },
- { 0, 17, 0, 7, 5, -1, 0, 11, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 92 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 92 },
- { 10, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 92 },
- { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 92 },
- { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 92 },
- { 10, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 16, 14, 9, 0, 92 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 101 },
- { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 101 },
- { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 96 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 96 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 96 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 96 },
- { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 96 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 96 },
- { 0, 17, 0, 9, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 96 },
- { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 96 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 96 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 96 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 96 },
- { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 96 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 96 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 111 },
- { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 111 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 111 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 111 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 100 },
- { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 100 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 100 },
- { 1, 0, 0, 9, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 100 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 15, 8, 1, 100 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 100 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 100 },
- { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 100 },
- { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 100 },
- { 0, 17, 0, 7, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 100 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 12, 1, 100 },
- { 1, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 100 },
- { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 100 },
- { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 100 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 100 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 100 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 100 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 100 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 100 },
- { 5, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 20 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 109 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 109 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 109 },
- { 1, 0, 0, 9, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 109 },
- { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 109 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 109 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 109 },
- { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 109 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 109 },
- { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 109 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 129 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 129 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 123 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 123 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 123 },
- { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 123 },
- { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 123 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 123 },
- { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 107 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 107 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 107 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 107 },
- { 0, 17, 0, 7, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 107 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 21, 8, 1, 107 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 107 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 107 },
- { 1, 0, 0, 9, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 41, 4, 1, 107 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 107 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 107 },
- { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 107 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 170 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 170 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 170 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 17, 8, 1, 170 },
- { 1, 0, 0, 0, 0, -1, 0, 27, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 170 },
- { 1, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 170 },
- { 0, 17, 0, 0, 5, -1, 0, 27, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 170 },
- { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 170 },
- { 1, 0, 0, 0, 0, -1, 0, 27, 3, 221, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 170 },
- { 0, 17, 0, 9, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 170 },
- { 1, 0, 0, 9, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 170 },
- { 0, 17, 0, 9, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 41, 4, 1, 170 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 39, 8, 1, 170 },
- { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 12, 1, 170 },
- { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 170 },
- { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 135 },
- { 1, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 135 },
- { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 135 },
- { 0, 17, 0, 9, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 135 },
- { 0, 17, 0, 7, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 135 },
- { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 135 },
- { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 135 },
- { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 135 },
- { 3, 0, 0, 0, 0, 0, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 2, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 3, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 4, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 5, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 6, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 7, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 8, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 3, 0, 0, 0, 0, 9, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 135 },
- { 25, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 135 },
- { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 135 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 135 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 135 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 124 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 124 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 124 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 124 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 124 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 124 },
- { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 124 },
- { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 124 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 124 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 124 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 122 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 122 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 122 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 122 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 122 },
- { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 122 },
- { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 122 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 122 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 122 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 0, 1, 122 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 122 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 122 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 122 },
- { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 122 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 114 },
- { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 114 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 114 },
- { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 114 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 114 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 114 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 114 },
- { 25, 10, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 33 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 102 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 102 },
- { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 102 },
- { 1, 0, 0, 9, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 102 },
- { 0, 17, 0, 7, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 102 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 102 },
- { 25, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 102 },
- { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 102 },
- { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 24 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 126 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 126 },
- { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 126 },
- { 1, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 44, 4, 1, 126 },
- { 1, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 4, 44, 4, 1, 126 },
- { 0, 17, 0, 9, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 44, 4, 1, 126 },
- { 3, 0, 0, 0, 0, 0, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 2, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 3, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 4, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 5, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 6, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 7, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 8, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 3, 0, 0, 0, 0, 9, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 126 },
- { 5, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 0, 1, 126 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 126 },
- { 29, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 0, 1, 126 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 44, 8, 1, 126 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 142 },
- { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 142 },
- { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 142 },
- { 0, 17, 0, 9, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 142 },
- { 0, 17, 0, 7, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 142 },
- { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 142 },
- { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 125 },
- { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 125 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 125 },
- { 5, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 125 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 125 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 154 },
- { 1, 0, 0, 0, 0, -1, 0, 23, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 154 },
- { 1, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 154 },
- { 1, 0, 0, 0, 0, -1, 0, 23, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 154 },
- { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 154 },
- { 1, 0, 0, 9, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 154 },
- { 0, 17, 0, 9, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 41, 4, 1, 154 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 39, 8, 1, 154 },
- { 0, 17, 0, 7, 5, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 154 },
- { 25, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 154 },
- { 25, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 154 },
- { 3, 0, 0, 0, 0, 0, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 2, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 3, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 4, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 5, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 6, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 7, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 8, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 3, 0, 0, 0, 0, 9, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 154 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 150 },
- { 1, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 150 },
- { 0, 17, 0, 0, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 150 },
- { 0, 17, 0, 9, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 150 },
- { 25, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 150 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 141 },
- { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 141 },
- { 0, 0, 0, 0, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 141 },
- { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 141 },
- { 1, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 141 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 15, 8, 1, 141 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 141 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 141 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 141 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 141 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 140 },
- { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 140 },
- { 1, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 140 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 15, 8, 1, 140 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 15, 8, 1, 140 },
- { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 140 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 140 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 140 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 140 },
- { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 140 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 29 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 119 },
- { 25, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 11 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 168 },
- { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 168 },
- { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 168 },
- { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 133 },
- { 1, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 133 },
- { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 133 },
- { 0, 0, 0, 9, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 133 },
- { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 133 },
- { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 133 },
- { 3, 0, 0, 0, 0, 0, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 2, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 3, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 4, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 5, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 6, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 7, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 8, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 3, 0, 0, 0, 0, 9, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 133 },
- { 5, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 133 },
- { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 24, 0, 1, 134 },
- { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 9, 0, 1, 134 },
- { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 134 },
- { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 134 },
- { 1, 0, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 134 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 138 },
- { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 138 },
- { 0, 17, 0, 7, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 138 },
- { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 138 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 15, 8, 1, 138 },
- { 3, 0, 0, 0, 0, 0, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 2, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 3, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 4, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 5, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 6, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 7, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 8, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 3, 0, 0, 0, 0, 9, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 138 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 143 },
- { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 143 },
- { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 143 },
- { 0, 17, 0, 9, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 143 },
- { 3, 0, 0, 0, 0, 0, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 2, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 3, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 4, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 5, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 6, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 7, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 8, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 3, 0, 0, 0, 0, 9, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 143 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 145 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 21, 8, 1, 145 },
- { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 145 },
- { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 145 },
- { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 145 },
- { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 162 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 7, 10, 39, 8, 1, 162 },
- { 1, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 162 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 38, 8, 1, 162 },
- { 1, 0, 0, 9, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 162 },
- { 0, 17, 0, 9, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 41, 4, 1, 162 },
- { 25, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 162 },
- { 25, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 162 },
- { 3, 0, 0, 0, 0, 0, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 2, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 3, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 4, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 5, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 6, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 7, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 8, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 3, 0, 0, 0, 0, 9, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 162 },
- { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 162 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 83 },
- { 5, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 16 },
- { 29, 10, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 16 },
- { 27, 4, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 16 },
- { 25, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 16 },
- { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 63 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 63 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 63 },
- { 4, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 63 },
- { 4, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 63 },
- { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 63 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 63 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 157 },
- { 25, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 157 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 81 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 0, 8, 1, 81 },
- { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 1, 8, 1, 81 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 0, 8, 1, 81 },
- { 10, 0, 0, 0, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 7, 4, 0, 81 },
- { 10, 0, 0, 0, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 0, 4, 0, 81 },
- { 10, 0, 0, 0, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 1, 4, 0, 81 },
- { 10, 0, 0, 0, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 7, 4, 0, 81 },
- { 10, 0, 0, 0, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 0, 4, 0, 81 },
- { 10, 0, 0, 0, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 1, 4, 0, 81 },
- { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 81 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 81 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 81 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 127 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 0, 8, 1, 127 },
- { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 1, 8, 1, 127 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 40, 8, 1, 165 },
- { 0, 17, 0, 0, 5, -1, 0, 27, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 165 },
- { 0, 17, 0, 0, 5, -1, 0, 27, 3, 221, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 165 },
- { 1, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 165 },
- { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 165 },
- { 0, 17, 0, 9, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 165 },
- { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 40, 9, 1, 165 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 84 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 115 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 115 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 115 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 159 },
- { 3, 0, 0, 0, 0, 0, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 2, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 3, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 4, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 5, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 6, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 7, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 8, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 3, 0, 0, 0, 0, 9, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 159 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 104 },
- { 0, 17, 0, 1, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 104 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 104 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 108 },
- { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 108 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 108 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 108 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 108 },
- { 29, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 108 },
- { 17, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 108 },
- { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 108 },
- { 5, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 108 },
- { 17, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 166 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 166 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 15, 8, 1, 166 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 204, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 15, 8, 1, 166 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 221, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 15, 8, 1, 166 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 17, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 10, 10, 15, 8, 1, 166 },
- { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 166 },
- { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 166 },
- { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 166 },
- { 14, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 32}, {0, 0}, {0, 0}, {0, 32} } }, 0, 10, 15, 7, 3, 146 },
- { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, -32}, {0, -32}, {0, 0} } }, 0, 10, 15, 6, 1, 146 },
- { 5, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 146 },
- { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 146 },
- { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 146 },
- { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 146 },
- { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 99 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 99 },
- { 0, 17, 0, 0, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 99 },
- { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 99 },
- { 1, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 8, 4, 27, 4, 1, 99 },
- { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 99 },
- { 17, 0, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 99 },
- { 17, 0, 0, 0, 0, -1, 0, 18, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 8, 8, 1, 137 },
- { 17, 0, 0, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 8, 8, 1, 139 },
- { 25, 10, 0, 0, 0, -1, 0, 21, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 0, 1, 37 },
- { 17, 0, 0, 0, 0, -1, 0, 21, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 8, 8, 1, 37 },
- { 0, 17, 0, 0, 5, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 7, 4, 1, 155 },
- { 1, 0, 0, 6, 0, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 18, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 137 },
- { 18, 0, 0, 0, 0, -1, 0, 20, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 137 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 137 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 137 },
- { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 8, 1, 155 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 8, 1, 155 },
- { 17, 0, 0, 0, 0, -1, 0, 24, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 15, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 17, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 8, 1, 34 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 8, 8, 8, 1, 35 },
- { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 139 },
- { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 105 },
- { 29, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 105 },
- { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 105 },
- { 0, 17, 0, 1, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 105 },
- { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 105 },
- { 10, 18, 0, 0, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 2, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 1, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 2, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 3, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 4, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 5, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 6, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 7, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 8, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 9, 0, 27, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 29, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 5, 3, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 1, 0, 0, 216, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 2 },
- { 0, 17, 0, 1, 5, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 1, 0, 0, 226, 0, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 2 },
- { 10, 18, 0, 0, 5, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 2, 2 },
- { 0, 17, 0, 220, 5, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 0, 17, 0, 230, 5, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 1 },
- { 29, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 4 },
- { 5, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 0, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 0, 0, 0, 0, -1, 0, 9, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 5, 0, 0, 0, 0, -1, 0, 20, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 7, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 26, 10, 0, 0, 0, -1, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 14, 0, 0, 0, 0, -1, 0, 9, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 2 },
- { 15, 0, 0, 0, 0, -1, 0, 9, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 1, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 2, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 3, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 4, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 5, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 6, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 7, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 8, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 9, 0, 5, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 131 },
- { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 131 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 0, 1, 131 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 21, 12, 1, 131 },
- { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 131 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 3 },
- { 15, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 1, 3 },
- { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 57 },
- { 17, 0, 0, 0, 0, -1, 0, 25, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 6, 3, 5 },
- { 0, 17, 0, 230, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 5 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 151 },
- { 0, 17, 0, 230, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 151 },
- { 17, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 151 },
- { 3, 0, 0, 0, 0, 0, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 2, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 3, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 4, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 5, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 6, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 7, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 8, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 3, 0, 0, 0, 0, 9, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 151 },
- { 29, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 151 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 160 },
- { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 160 },
- { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 152 },
- { 0, 17, 0, 230, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 152 },
- { 3, 0, 0, 0, 0, 0, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 2, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 3, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 4, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 5, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 6, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 7, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 8, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 3, 0, 0, 0, 0, 9, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 152 },
- { 27, 4, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 12, 0, 1, 152 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 163 },
- { 17, 0, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 163 },
- { 0, 17, 0, 232, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 163 },
- { 0, 17, 0, 220, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 163 },
- { 0, 17, 0, 230, 5, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 163 },
- { 3, 0, 0, 0, 0, 0, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 2, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 3, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 4, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 5, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 6, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 7, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 8, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 3, 0, 0, 0, 0, 9, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 163 },
- { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 167 },
- { 0, 17, 0, 230, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 167 },
- { 0, 17, 0, 220, 5, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 167 },
- { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 167 },
- { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 167 },
- { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 27 },
- { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 113 },
- { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 113 },
- { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 113 },
- { 14, 1, 0, 0, 2, -1, 0, 18, 3, 0, { { { 0, 34}, {0, 0}, {0, 0}, {0, 34} } }, 0, 10, 15, 7, 3, 132 },
- { 15, 1, 0, 0, 2, -1, 0, 18, 3, 0, { { { 0, 0}, {0, -34}, {0, -34}, {0, 0} } }, 0, 10, 15, 6, 1, 132 },
- { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 132 },
- { 0, 17, 0, 7, 5, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 1, 132 },
- { 17, 1, 0, 0, 5, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 1, 132 },
- { 3, 1, 0, 0, 0, 0, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 2, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 3, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 4, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 5, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 6, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 7, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 8, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 3, 1, 0, 0, 0, 9, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 1, 132 },
- { 25, 1, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 0, 0, 1, 132 },
- { 5, 13, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 13, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 27, 13, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 13, 0, 1, 2 },
- { 5, 13, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 13, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 18, 13, 0, 0, 0, -1, 0, 13, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 8, 3, 8 },
- { 26, 10, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 8 },
- { 29, 10, 3, 0, 0, -1, 0, 10, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 13, 0, 0, 0, 0, -1, 0, 0, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 0, 0 },
- { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 5, 2, 0, 0, 0, 0, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 2 },
- { 5, 2, 0, 0, 0, 0, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 1, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 2, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 3, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 4, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 5, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 6, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 7, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 8, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 2, 0, 0, 0, 9, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 5, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 23, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 12, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 12, 0, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 12, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 10, 15, 7, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 13, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 21, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 3, 2 },
- { 29, 0, 1, 0, 0, -1, 0, 12, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 10, 15, 7, 1, 2 },
- { 29, 0, 1, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 10, 15, 7, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 0, 3, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 12, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 18, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 0, 19, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 6, 7, 34, 0, 1, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 11, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 34 },
- { 29, 0, 3, 0, 0, -1, 0, 12, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 3, 2 },
- { 29, 0, 1, 0, 0, -1, 0, 12, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 3, 2 },
- { 29, 0, 3, 0, 0, -1, 0, 11, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 3, 2 },
- { 29, 0, 0, 0, 0, -1, 0, 18, 5, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 3, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 1, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 17, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 16, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 9, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 28, 10, 23, 0, 0, -1, 0, 17, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 37, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 13, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 17, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 18, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 16, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 18, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 13, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 3, 13, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 8, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 19, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 21, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 25, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 24, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 20, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 25, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 20, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 13, 0, 0, 0, 0, -1, 0, 0, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 0, 0 },
- { 29, 10, 0, 0, 0, -1, 0, 27, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 23, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 21, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 17, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 19, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 18, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 0, 1, 2 },
- { 29, 10, 19, 0, 0, -1, 0, 20, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 20, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 0, 0, 0, -1, 0, 21, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 15, 0, 1, 2 },
- { 29, 10, 3, 0, 0, -1, 0, 27, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 17, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 24, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 29, 10, 11, 0, 0, -1, 0, 25, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 14, 0, 36, 0, 1, 2 },
- { 3, 2, 0, 0, 0, 0, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 1, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 2, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 3, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 4, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 5, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 6, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 7, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 8, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 3, 2, 0, 0, 0, 9, 0, 23, 3, 80, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 16, 14, 9, 3, 2 },
- { 13, 18, 0, 0, 0, -1, 0, 2, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 },
- { 18, 0, 0, 0, 0, -1, 0, 5, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 25, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 26, 5, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 1, 37 },
- { 18, 0, 0, 0, 0, -1, 0, 5, 5, 85, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 17, 8, 3, 37 },
- { 10, 18, 0, 0, 5, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 3, 6, 27, 4, 0, 2 },
- { 10, 18, 16, 0, 5, -1, 0, 5, 3, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 0, 2 },
- { 0, 17, 0, 0, 5, -1, 0, 7, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 4, 4, 27, 4, 2, 1 },
- { 12, 0, 0, 0, 0, -1, 0, 2, 0, 0, { { { 0, 0}, {0, 0}, {0, 0}, {0, 0} } }, 0, 0, 15, 0, 0, 0 }
+ { 9, 18, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 0, 27, 0, 1, 2, 0 },
+ { 9, 8, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 0, 21, 5, 1, 2, 0 },
+ { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, 0, 2, 2, 48, 2, 1, 2, 0 },
+ { 9, 8, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 3, 49, 5, 1, 2, 0 },
+ { 9, 9, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 3, 49, 5, 1, 2, 0 },
+ { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, 0, 1, 1, 47, 1, 1, 2, 0 },
+ { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 0, 27, 0, 1, 2, 0 },
+ { 9, 8, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 0, 27, 0, 1, 2, 0 },
+ { 6, 9, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 18, 46, 5, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 9, 12, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 12, 3, 13, 1, 2, 0 },
+ { 25, 4, 17, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 11, 3, 13, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 4, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 4, 0, 0, 0, 0, 2, 13, 1, 2, 0 },
+ { 25, 10, 17, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 3, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 15, 11, 11, 1, 2, 0 },
+ { 20, 3, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 19, 11, 1, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 15, 11, 10, 1, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 10, 0, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 0, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 1, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 2, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 3, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 4, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 5, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 6, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 7, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 8, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 3, 2, 17, 0, 0, 9, 0, 1, 4, 0, 0, 0, 16, 14, 9, 1, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 11, 11, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 15, 11, 11, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 4, 0, 1, 0, 10, 15, 7, 3, 3, 0 },
+ { 21, 10, 0, 0, 0, -1, 2, 1, 4, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -2, 1, 4, 0, 0, 0, 0, 2, 13, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 19, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 17, 15, 0, 1, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 4, 0, 2, 0, 10, 15, 6, 1, 3, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -2, 1, 4, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 9, 18, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 0, 27, 0, 0, 2, 0 },
+ { 9, 7, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 3, 49, 3, 0, 2, 0 },
+ { 6, 6, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 7, 5, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 4, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 1, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 23, 10, 0, 0, 0, -1, 16, 1, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 1, 0, 0, 0, 3, 6, 21, 4, 2, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 1, 0, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 4, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 4, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 26, 4, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 5, 2, 0, 0, 0, 2, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 3, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 24, 0, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 3, 0, 10, 15, 6, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 14, 15, 0, 1, 2, 0 },
+ { 5, 2, 0, 0, 0, 1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 24, 10, 0, 0, 0, -1, -16, 1, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 1, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 10, 15, 7, 3, 3, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 4, 0, 10, 15, 6, 4, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, 2, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 2, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 2, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 5, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 8, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 9, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 80, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 80, 7, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 80, 10, 0, 10, 15, 6, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 11, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 12, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 13, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 14, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 15, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 16, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 17, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 18, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 19, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 20, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 21, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 22, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 23, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 24, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 25, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 26, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 27, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 28, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 29, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 30, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 31, 0, 10, 15, 7, 3, 3, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 32, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 80, 33, 0, 10, 15, 7, 3, 3, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 80, 34, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 35, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 36, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 37, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 38, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 39, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 17, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 17, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 6, 3, 0, 40, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 41, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 42, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 43, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 44, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 45, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 46, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 47, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 48, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 49, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 50, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 51, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 52, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 53, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 54, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 55, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 56, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 57, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 58, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 59, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 60, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 61, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 62, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 63, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 64, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 65, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 66, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 67, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 68, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 69, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 70, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 71, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 72, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 73, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 74, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 75, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 76, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 77, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 78, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 79, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 80, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 6, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 24, 8, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 4, 0, 0, 0, 0, 10, 24, 0, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 0, 1, 36, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 1, 0, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 1, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 232, 5, -1, 0, 1, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 1, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 216, 5, -1, 0, 1, 0, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 202, 5, -1, 0, 1, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 1, 0, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 202, 5, -1, 0, 1, 0, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 1, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 1, 0, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 1, 0, 85, 0, 4, 4, 27, 4, 3, 1, 0 },
+ { 0, 17, 0, 240, 5, -1, 0, 1, 0, 204, 81, 4, 4, 27, 4, 3, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 4, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 4, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 6, 0, 0, 0, 4, 4, 7, 4, 2, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 7, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 7, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 232, 5, -1, 0, 8, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 8, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 8, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 233, 5, -1, 0, 8, 0, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 234, 5, -1, 0, 7, 0, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 233, 5, -1, 0, 7, 0, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 234, 5, -1, 0, 1, 0, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 233, 5, -1, 0, 4, 0, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 6, 0, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 6, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, 7, 0, 10, 15, 6, 1, 4, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 10, 15, 8, 3, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 4, 0 },
+ { 13, 0, 0, 0, 0, -1, 0, 0, 3, 0, 0, 0, 0, 15, 0, 0, 0, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 27, 0, 10, 15, 6, 1, 4, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 15, 11, 11, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 82, 0, 10, 15, 7, 3, 4, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 4, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 81, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 83, 0, 10, 15, 7, 3, 4, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 14, 15, 0, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 84, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 85, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 86, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 87, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 1, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 88, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 89, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 90, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 2, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 91, 0, 10, 15, 6, 4, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 2, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 92, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 93, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 94, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 95, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 96, 0, 10, 15, 6, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 81, 0, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 97, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 98, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, 99, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 6, 3, 0, 6, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 6, 3, 0, 7, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 6, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, 7, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 6, 0, 10, 15, 7, 3, 46, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 7, 0, 10, 15, 6, 1, 46, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 100, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 101, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 102, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 103, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 5, 3, 80, 104, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 5, 3, 80, 105, 0, 10, 15, 6, 3, 4, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 0, 15, 0, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 7, 3, 0, 6, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, 7, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 7, 3, 80, 106, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 40, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 17, 107, 0, 10, 15, 7, 3, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 17, 107, 0, 10, 15, 7, 3, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 107, 0, 10, 15, 7, 3, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 107, 0, 10, 15, 7, 3, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 10, 15, 7, 3, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 17, 1, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 0, 2, 0, 10, 15, 6, 1, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, 2, 0, 10, 15, 6, 1, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 17, 108, 0, 10, 15, 6, 1, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 17, 108, 0, 10, 15, 6, 1, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 108, 0, 10, 15, 6, 1, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 108, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 5, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 5, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 5, 0 },
+ { 2, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 6, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 6, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 109, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 110, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 17, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 4, 3, 17, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 11, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 12, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 12, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 111, 0, 10, 15, 7, 3, 6, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 6, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 0, 1, 6, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 11, 1, 6, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 14, 15, 0, 1, 6, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 6, 1, 6, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 112, 0, 10, 15, 6, 1, 6, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 113, 0, 10, 15, 6, 3, 6, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 15, 11, 12, 1, 6, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 21, 0, 1, 6, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 6, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 12, 0, 1, 6, 0 },
+ { 13, 1, 0, 0, 0, -1, 0, 0, 3, 0, 0, 0, 0, 15, 0, 0, 0, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 222, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 228, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 10, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 11, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 12, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 13, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 14, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 15, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 16, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 17, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 18, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 19, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 19, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 20, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 21, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 22, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 20, 1, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 21, 0, 1, 7, 0 },
+ { 0, 17, 0, 23, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 7, 0 },
+ { 0, 17, 0, 24, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 0, 17, 0, 25, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 9, 0, 1, 7, 0 },
+ { 0, 17, 0, 18, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 9, 16, 8, 1, 7, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 9, 16, 8, 1, 7, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 7, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 14, 15, 0, 1, 7, 0 },
+ { 10, 5, 0, 0, 0, -1, 0, 7, 3, 0, 0, 7, 16, 14, 9, 0, 8, 0 },
+ { 10, 5, 0, 0, 0, -1, 0, 13, 3, 0, 0, 7, 16, 14, 9, 0, 8, 0 },
+ { 10, 5, 0, 0, 0, -1, 0, 16, 3, 0, 0, 7, 16, 14, 9, 0, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 26, 13, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 13, 0, 1, 8, 0 },
+ { 27, 13, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 13, 0, 1, 8, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 15, 11, 11, 1, 2, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 15, 11, 11, 1, 8, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 30, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 31, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 32, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 9, 0, 1, 2, 0 },
+ { 10, 13, 0, 0, 5, -1, 0, 15, 3, 0, 0, 3, 6, 27, 4, 0, 8, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 9, 12, 1, 8, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 9, 12, 1, 8, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 9, 12, 1, 2, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 1, 3, 17, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 1, 3, 17, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 17, 13, 0, 0, 1, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 0, 17, 0, 27, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 28, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 29, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 30, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 31, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 32, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 33, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 34, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 4, 3, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 4, 3, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 5, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 13, 0, 1, 8, 0 },
+ { 25, 5, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 25, 5, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 15, 14, 9, 1, 8, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 6, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 0, 17, 0, 35, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 1, 3, 80, 0, 0, 10, 15, 8, 3, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 1, 3, 80, 0, 0, 10, 15, 8, 3, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 9, 12, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 10, 5, 0, 0, 0, -1, 0, 1, 3, 0, 0, 7, 16, 14, 9, 0, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 17, 13, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 3, 2, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 8, 0 },
+ { 29, 13, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 12, 1, 9, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 9, 0 },
+ { 13, 13, 0, 0, 0, -1, 0, 0, 3, 0, 0, 0, 0, 15, 0, 0, 0, 0 },
+ { 10, 13, 0, 0, 5, -1, 0, 4, 3, 0, 0, 7, 10, 15, 4, 0, 9, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 9, 0 },
+ { 0, 17, 0, 36, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 9, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 9, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 9, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 9, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 9, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 9, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 10, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 10, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 10, 15, 8, 1, 10, 0 },
+ { 3, 1, 0, 0, 0, 0, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 1, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 2, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 3, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 4, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 5, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 6, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 7, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 8, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 3, 1, 0, 0, 0, 9, 0, 9, 3, 0, 0, 0, 16, 14, 9, 1, 66, 0 },
+ { 18, 1, 0, 0, 2, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 66, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 66, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 66, 0 },
+ { 17, 1, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 66, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 15, 0, 1, 66, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 15, 0, 1, 66, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 15, 11, 11, 1, 66, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 9, 12, 1, 66, 0 },
+ { 17, 1, 0, 0, 1, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 66, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 66, 0 },
+ { 27, 1, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 12, 0, 1, 66, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 82, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 82, 0 },
+ { 17, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 82, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 82, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 12, 1, 82, 0 },
+ { 18, 1, 0, 0, 3, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 95, 0 },
+ { 18, 1, 0, 0, 2, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 95, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 95, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 15, 0, 1, 95, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 9, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 9, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 9, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 1, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 28, 13, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 10, 5, 0, 0, 0, -1, 0, 24, 3, 0, 0, 7, 16, 14, 9, 0, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 18, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 18, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 17, 13, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 10, 5, 0, 0, 0, -1, 0, 18, 3, 0, 0, 7, 16, 14, 9, 0, 2, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 17, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 27, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 28, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 29, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 11, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 11, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 17, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 11, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 8, 4, 27, 4, 1, 11, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 11, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 11, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 8, 4, 27, 4, 1, 11, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 10, 15, 8, 3, 11, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 21, 12, 1, 2, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 11, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 11, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 12, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 12, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 12, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 12, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 12, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 12, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 12, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, 0, 8, 4, 27, 4, 1, 12, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 12, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 12, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 10, 15, 8, 3, 12, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 12, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 13, 0, 1, 12, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 12, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 13, 0, 1, 12, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 12, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 12, 0, 1, 12, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 12, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 15, 0, 1, 12, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 12, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 13, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 13, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 8, 4, 27, 4, 1, 13, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 13, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 10, 15, 8, 3, 13, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 13, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 13, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 13, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 13, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 13, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 14, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 14, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 14, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 14, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 14, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 14, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 14, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 15, 0, 1, 14, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 12, 0, 1, 14, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 14, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 14, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 15, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 15, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 15, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 15, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 15, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 15, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 15, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, 0, 8, 4, 27, 4, 1, 15, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 15, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 15, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 15, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 10, 15, 8, 3, 15, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 15, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 15, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 15, 0, 1, 15, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 16, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 16, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 17, 0, 0, 10, 15, 8, 1, 16, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 16, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 16, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 16, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, 0, 8, 4, 27, 4, 1, 16, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 16, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 16, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 16, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 16, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 12, 0, 1, 16, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 17, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 17, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 17, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 17, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 17, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 0, 17, 0, 84, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 0, 17, 0, 91, 5, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 17, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 17, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 17, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 24, 0, 1, 17, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 17, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 17, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 10, 15, 8, 1, 18, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 18, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 24, 0, 1, 18, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 18, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 18, 0 },
+ { 0, 0, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 18, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 18, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 18, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 8, 4, 27, 4, 1, 18, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 19, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 19, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 8, 4, 27, 4, 1, 19, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 19, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 19, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 19, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 19, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 19, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 204, 0, 4, 4, 27, 4, 1, 19, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 19, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 19, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 1, 3, 17, 0, 8, 4, 27, 4, 1, 19, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 19, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 7, 10, 15, 8, 1, 19, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 15, 0, 1, 19, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 10, 15, 8, 1, 19, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 15, 0, 1, 19, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 19, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 19, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 13, 0, 1, 19, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 20, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 8, 4, 27, 4, 1, 20, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 20, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 4, 3, 204, 0, 4, 4, 27, 4, 1, 20, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 4, 3, 204, 0, 4, 4, 27, 4, 1, 20, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 20, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 4, 3, 17, 0, 8, 4, 27, 4, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 20, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 20, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 44, 8, 1, 21, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 44, 4, 1, 21, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 8, 0, 44, 8, 3, 21, 0 },
+ { 0, 17, 0, 103, 5, -1, 0, 1, 3, 0, 0, 4, 4, 44, 4, 1, 21, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 1, 3, 0, 0, 4, 4, 44, 4, 1, 21, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 44, 8, 1, 21, 0 },
+ { 0, 17, 0, 107, 5, -1, 0, 1, 3, 0, 0, 4, 4, 44, 4, 1, 21, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 21, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 21, 0, 1, 21, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 44, 8, 1, 22, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 44, 8, 1, 22, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 44, 4, 1, 22, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 8, 0, 44, 8, 3, 22, 0 },
+ { 0, 17, 0, 118, 5, -1, 0, 1, 3, 0, 0, 4, 4, 44, 4, 1, 22, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 21, 3, 0, 0, 4, 4, 44, 4, 1, 22, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 44, 8, 1, 22, 0 },
+ { 0, 17, 0, 122, 5, -1, 0, 1, 3, 0, 0, 4, 4, 44, 4, 1, 22, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, 0, 4, 4, 44, 4, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 16, 14, 9, 1, 22, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 44, 8, 3, 22, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 44, 8, 1, 22, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 10, 15, 8, 1, 23, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 24, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 24, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 15, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 7, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 21, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 2, 3, 80, 0, 0, 0, 7, 0, 3, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 9, 0, 1, 23, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 15, 0, 1, 23, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 2, 3, 0, 0, 0, 16, 14, 9, 1, 23, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 15, 0, 1, 23, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 21, 0, 1, 23, 0 },
+ { 0, 17, 0, 216, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 2, 3, 0, 0, 0, 0, 0, 13, 1, 23, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 2, 3, 0, 0, 0, 0, 1, 13, 1, 23, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 8, 4, 27, 4, 1, 23, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 2, 3, 85, 0, 0, 10, 15, 8, 3, 23, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 23, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 23, 0 },
+ { 0, 17, 0, 129, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 0, 17, 0, 130, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 2, 3, 85, 0, 4, 4, 27, 4, 3, 23, 0 },
+ { 0, 17, 0, 132, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 2, 3, 80, 0, 4, 4, 27, 4, 3, 23, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 8, 4, 21, 4, 1, 23, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 2, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 23, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 0, 1, 23, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 23, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 23, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 24, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 24, 0, 1, 23, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 23, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 7, 0, 1, 23, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 44, 8, 1, 24, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 44, 8, 1, 24, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 17, 0, 0, 0, 44, 8, 1, 24, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 4, 44, 4, 1, 24, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 4, 44, 4, 1, 24, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 204, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 8, 4, 44, 4, 1, 24, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 4, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 4, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 10, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 8, 4, 44, 4, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 12, 1, 24, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 24, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 10, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 4, 44, 4, 1, 24, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 44, 0, 1, 24, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 114, 0, 10, 15, 7, 3, 25, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, 114, 0, 10, 15, 7, 3, 25, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 0, 115, 0, 10, 15, 8, 1, 25, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 6, 3, 0, 115, 0, 10, 15, 8, 1, 25, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 115, 0, 10, 15, 8, 1, 25, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, 0, 0, 10, 15, 6, 3, 25, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, 115, 0, 10, 15, 8, 1, 25, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 9, 10, 31, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 5, 0, 0, 9, 10, 31, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 9, 10, 31, 8, 2, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 10, 10, 32, 8, 2, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 204, 0, 10, 10, 32, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 10, 10, 32, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 10, 10, 32, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 204, 0, 11, 10, 33, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 11, 10, 33, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 11, 10, 33, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 27, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 27, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 27, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 27, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 0, 1, 27, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 12, 1, 27, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 2, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 3, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 4, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 5, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 6, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 7, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 8, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, 9, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 27, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 116, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 117, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 118, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 119, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 120, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 121, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 122, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 123, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 124, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 125, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 126, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 127, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 128, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 129, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 130, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 131, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 132, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 133, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 134, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 135, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 136, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 137, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 138, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 139, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 140, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 141, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 142, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 143, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 144, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 145, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 146, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 147, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 148, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 149, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 150, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 151, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 152, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 153, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 154, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 155, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 156, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 157, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 158, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 159, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 160, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 161, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 162, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 163, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 164, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 165, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 166, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 167, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 168, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 169, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 170, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 171, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 172, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 173, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 174, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 175, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 176, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 177, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 178, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 179, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 180, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 181, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 182, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 183, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 184, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 185, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 186, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 187, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 188, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 189, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 190, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 191, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 192, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 193, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 194, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 195, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 4, 3, 0, 196, 0, 10, 15, 7, 1, 28, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, 196, 0, 10, 15, 7, 1, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 197, 0, 10, 15, 6, 3, 28, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 0, 1, 29, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 29, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 29, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 12, 1, 29, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 29, 0 },
+ { 6, 9, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 18, 21, 5, 0, 30, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 30, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 4, 3, 0, 0, 0, 0, 0, 13, 1, 30, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 4, 3, 0, 0, 0, 0, 1, 13, 1, 30, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 31, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 31, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 31, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 10, 15, 8, 1, 42, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 42, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 42, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 42, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 42, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 10, 15, 8, 1, 43, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 43, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 43, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 0, 21, 12, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 10, 15, 8, 1, 44, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 44, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 10, 15, 8, 1, 45, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 45, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 44, 8, 1, 32, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 44, 4, 2, 32, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 8, 4, 44, 4, 1, 32, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 44, 4, 1, 32, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 4, 3, 0, 0, 4, 4, 44, 4, 1, 32, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 12, 1, 32, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 8, 0, 1, 32, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 44, 8, 1, 32, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 0, 1, 32, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 32, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 12, 0, 1, 32, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 7, 3, 0, 0, 4, 4, 44, 4, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 32, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 32, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 33, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 9, 11, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 9, 12, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 0, 1, 33, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 24, 0, 1, 33, 0 },
+ { 25, 10, 0, 0, 2, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 33, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 9, 11, 1, 33, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 9, 12, 1, 33, 0 },
+ { 25, 10, 0, 0, 1, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 33, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 2, 33, 0 },
+ { 10, 18, 0, 0, 0, -1, 0, 4, 3, 0, 0, 3, 6, 7, 4, 2, 33, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 2, 33, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 4, 3, 0, 0, 0, 16, 14, 9, 1, 33, 0 },
+ { 18, 0, 0, 0, 2, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 33, 0 },
+ { 17, 0, 0, 0, 2, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 33, 0 },
+ { 18, 0, 0, 0, 2, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 33, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 10, 15, 8, 1, 33, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 33, 0 },
+ { 0, 17, 0, 228, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 33, 0 },
+ { 18, 0, 0, 0, 2, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 33, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 47, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 47, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 47, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 8, 4, 27, 4, 1, 47, 0 },
+ { 0, 17, 0, 222, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 47, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 47, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 7, 3, 0, 0, 4, 4, 27, 4, 1, 47, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 47, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 9, 12, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 47, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 44, 8, 1, 48, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 44, 8, 1, 56, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 8, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 8, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 5, 0, 0, 0, 0, 1, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 56, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 44, 0, 1, 56, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 32, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 55, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 55, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 55, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 8, 4, 27, 4, 1, 55, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 55, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 55, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 8, 1, 78, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 8, 4, 44, 4, 1, 78, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, 0, 4, 4, 44, 4, 1, 78, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 11, 3, 0, 0, 4, 4, 44, 4, 1, 78, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 4, 44, 4, 1, 78, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, 0, 4, 4, 44, 4, 1, 78, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 78, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 0, 1, 78, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 8, 1, 78, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 12, 1, 78, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 2, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 62, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 8, 4, 27, 4, 1, 62, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 38, 8, 1, 62, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 9, 3, 17, 0, 0, 10, 38, 8, 1, 62, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 62, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 9, 3, 204, 0, 4, 4, 27, 4, 1, 62, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 9, 3, 17, 0, 4, 4, 27, 4, 1, 62, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 9, 3, 17, 0, 8, 4, 27, 4, 1, 62, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 9, 3, 0, 0, 4, 4, 41, 4, 1, 62, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 38, 8, 1, 62, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 21, 12, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 9, 3, 0, 0, 0, 16, 40, 9, 1, 62, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 21, 12, 1, 62, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 17, 0, 1, 62, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 21, 0, 1, 62, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 17, 0, 1, 62, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 62, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 62, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 21, 12, 1, 62, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 67, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 8, 4, 27, 4, 1, 67, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 67, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 67, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 67, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 67, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 67, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 40, 8, 1, 93, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 93, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 8, 4, 27, 4, 1, 93, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 93, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 12, 3, 0, 0, 4, 4, 42, 4, 1, 93, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 15, 0, 1, 93, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 68, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 8, 4, 27, 4, 1, 68, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 68, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 68, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 12, 1, 68, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 0, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 68, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 69, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 69, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 69, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 12, 1, 69, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 198, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 199, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 200, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 201, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 202, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 203, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 204, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 205, 0, 10, 15, 6, 3, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, 6, 0, 10, 15, 7, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 27, 3, 0, 7, 0, 10, 15, 6, 1, 5, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 20, 3, 0, 206, 0, 10, 15, 8, 3, 25, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 15, 0, 1, 67, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 8, 4, 27, 4, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 8, 4, 27, 4, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 6, 1, 5, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 7, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 7, 3, 80, 0, 0, 10, 15, 6, 3, 4, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, 0, 0, 10, 15, 6, 3, 5, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 207, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 208, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 209, 0, 10, 15, 6, 1, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, 0, 0, 10, 15, 6, 3, 4, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 9, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 234, 5, -1, 0, 10, 3, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 214, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 202, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 232, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 228, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 218, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 233, 5, -1, 0, 12, 3, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 210, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 211, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 212, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 213, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 214, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 2, 3, 81, 215, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 216, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 10, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 217, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 218, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 219, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 220, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 221, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 222, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 223, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 223, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 224, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 224, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 225, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 225, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 226, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 226, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 227, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 227, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 228, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 228, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 229, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 230, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 231, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 232, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 233, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 234, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 235, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 236, 0, 10, 15, 6, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 237, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 238, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 239, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 240, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 241, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 242, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 243, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 244, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 245, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 246, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 247, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 248, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 249, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 250, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 251, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 252, 0, 10, 15, 6, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 253, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 254, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 255, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 256, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 257, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 258, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 259, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 260, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 261, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 262, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 263, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 264, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 265, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 266, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 267, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 268, 0, 10, 15, 6, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 269, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 270, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 271, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 272, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 273, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 274, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 275, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 276, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 277, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 278, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 279, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 280, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 281, 0, 10, 15, 6, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 282, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, 282, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 283, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 284, 0, 10, 15, 6, 3, 4, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 81, 0, 0, 0, 15, 0, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 285, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 286, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 287, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 288, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 289, 0, 10, 15, 6, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 290, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, 290, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 291, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 292, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 293, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 294, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 295, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 296, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, 296, 0, 10, 15, 7, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 297, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 85, 298, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 299, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 102, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 300, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 301, 0, 10, 15, 6, 1, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 302, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, 302, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 106, 0, 10, 15, 7, 3, 4, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 0, 15, 0, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 303, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 304, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 305, 0, 10, 15, 6, 3, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 306, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 17, 307, 0, 10, 15, 6, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 308, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, 308, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 17, 309, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, 309, 0, 10, 15, 7, 3, 4, 0 },
+ { 16, 0, 0, 0, 0, -1, 0, 1, 3, 17, 310, 0, 10, 15, 7, 3, 4, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 0, 24, 0, 3, 4, 0 },
+ { 6, 9, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 18, 21, 5, 3, 2, 0 },
+ { 6, 9, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 18, 21, 5, 3, 2, 0 },
+ { 6, 9, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 7, 5, 3, 2, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 0, 26, 4, 2, 2, 0 },
+ { 10, 18, 0, 0, 0, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 4, 1, 0 },
+ { 10, 18, 16, 0, 1, -1, 0, 1, 3, 0, 0, 5, 5, 43, 4, 4, 1, 0 },
+ { 10, 0, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 1, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 7, 0, 3, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 21, 11, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 25, 11, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 23, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 13, 3, 13, 1, 2, 0 },
+ { 24, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 13, 3, 13, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 23, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 23, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 24, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 13, 18, 10, 0, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 18, 0, 0, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 14, 21, 0, 1, 2, 0 },
+ { 7, 9, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 3, 49, 3, 0, 2, 0 },
+ { 8, 7, 0, 0, 0, -1, 0, 1, 3, 0, 0, 3, 3, 49, 3, 0, 2, 0 },
+ { 10, 11, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 14, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 16, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 12, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 15, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 6, 6, 0, 0, 0, -1, 0, 4, 3, 80, 0, 0, 17, 7, 5, 3, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 23, 10, 0, 0, 0, -1, 1, 1, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 24, 10, 0, 0, 0, -1, -1, 1, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 25, 10, 1, 0, 0, -1, 0, 1, 3, 80, 0, 14, 0, 8, 12, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 8, 12, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 19, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 17, 15, 0, 1, 2, 0 },
+ { 26, 6, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 15, 11, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 3, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 0, 8, 12, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 80, 0, 0, 0, 8, 12, 3, 2, 0 },
+ { 25, 10, 1, 0, 0, -1, 0, 4, 3, 80, 0, 14, 0, 8, 12, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 19, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 17, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 6, 9, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 18, 21, 5, 3, 2, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 6, 3, 0, 0, 3, 6, 28, 4, 2, 2, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 6, 3, 0, 0, 3, 6, 15, 4, 2, 2, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 10, 3, 0, 0, 3, 6, 15, 4, 2, 2, 0 },
+ { 13, 18, 0, 0, 0, -1, 0, 0, 3, 0, 0, 3, 0, 15, 0, 0, 0, 0 },
+ { 10, 19, 0, 0, 0, -1, 0, 15, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 20, 0, 0, 0, -1, 0, 15, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 21, 0, 0, 0, -1, 0, 15, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 22, 0, 0, 0, -1, 0, 15, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 27, 4, 2, 2, 0 },
+ { 5, 2, 0, 0, 0, 0, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 5, 2, 0, 0, 0, 4, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 5, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 6, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 7, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 8, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 9, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 26, 3, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 3, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 3, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 12, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 12, 0, 3, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 2, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 3, 0, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 14, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 13, 4, 0, 0, 0, -1, 0, 0, 3, 0, 0, 0, 0, 12, 0, 0, 0, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 2, 17, 0, 0, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 2, 17, 0, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 2, 17, 16, 0, 5, -1, 0, 4, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 2, 17, 0, 0, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 6, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 10, 15, 7, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 10, 15, 6, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 10, 15, 6, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 12, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 1, 0, 80, 0, 14, 0, 15, 0, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 85, 311, 0, 10, 15, 7, 3, 4, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 85, 312, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 0, 85, 313, 0, 10, 15, 7, 3, 3, 0 },
+ { 29, 4, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 3, 0, 314, 0, 10, 15, 7, 3, 3, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 10, 15, 8, 3, 2, 0 },
+ { 15, 0, 1, 0, 0, -1, 0, 4, 3, 80, 0, 14, 10, 15, 6, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 80, 0, 0, 10, 15, 6, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 10, 15, 6, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 10, 15, 7, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 315, 0, 10, 15, 6, 1, 3, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 11, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 1, 0, 80, 316, 0, 10, 15, 7, 3, 3, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 1, 3, 80, 316, 0, 10, 15, 7, 3, 3, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 1, 0, 80, 317, 0, 10, 15, 6, 3, 3, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 1, 3, 80, 317, 0, 10, 15, 6, 3, 3, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 10, 15, 8, 1, 3, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 3, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 1, 0, 0, -1, 0, 1, 0, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 3, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 3, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 3, 1, 3, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 3, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -3, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -3, 1, 3, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -3, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 3, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 26, 4, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 12, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2016, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2527, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1923, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1914, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1918, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2250, 1, 3, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 138, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 7, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -7, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 0, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 1, 0, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 1, 0, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 1, 3, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 1, 3, 17, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1824, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2104, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2108, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2106, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1316, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -138, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 18, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 8, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 7, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -8, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -7, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 1, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 5, 85, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 5, 85, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 4, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 7, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 12, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 12, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 12, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 12, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 16, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 2, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 3, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 4, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 5, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 6, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 7, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 8, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 9, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 2, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 3, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 4, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 5, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 6, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 7, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 8, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 9, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 0, 80, 318, 0, 10, 15, 7, 3, 2, 0 },
+ { 29, 0, 1, 0, 0, -1, 0, 1, 0, 80, 318, 14, 10, 15, 7, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 0, 80, 319, 0, 10, 15, 6, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, 0, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 1, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 2, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 3, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 4, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 5, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 6, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 7, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 8, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 9, 0, 6, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 1, 0, 0, -1, 0, 6, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 3, 0, 0, -1, 0, 6, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 1, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 7, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 6, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 8, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 9, 0, 0, -1, 0, 1, 3, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 1, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 1, 0, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 6, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 8, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 8, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 5, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 8, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 11, 0, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 7, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 11, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 11, 0, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 11, 0, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 11, 0, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 9, 0, 0, -1, 0, 11, 0, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 12, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 11, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 9, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 1, 3, 0, 0, 14, 0, 9, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 6, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 6, 3, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 3, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 5, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 6, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 7, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 8, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 9, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 2, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 3, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 4, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 5, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 6, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 7, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 8, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, 9, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 8, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 8, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 8, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 8, 3, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 9, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 9, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2, 13, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2, 13, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1316, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 6, 4, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 6, 4, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 10, 4, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 10, 4, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 10, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 10, 3, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 4, 3, 0, 0, 0, 0, 15, 0, 1, 54, 0 },
+ { 21, 10, 0, 0, 0, -1, 3, 6, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, 1, 6, 3, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, -1, 6, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -3, 6, 3, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1914, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1918, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1923, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1824, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2016, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 6, 3, 85, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2104, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2106, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2108, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2250, 6, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 10, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 11, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, -2527, 20, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 111, 0, 10, 15, 7, 3, 57, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 24, 3, 0, 111, 0, 10, 15, 7, 3, 57, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 112, 0, 10, 15, 6, 1, 57, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, 112, 0, 10, 15, 6, 1, 57, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 320, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 321, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 0, 322, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 323, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 324, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 325, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 326, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 327, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, 328, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 10, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, 329, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, 330, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 8, 3, 0, 6, 0, 10, 15, 7, 3, 46, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 7, 0, 10, 15, 6, 1, 46, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 6, 1, 46, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 46, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 11, 3, 0, 6, 0, 10, 15, 7, 3, 46, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 11, 3, 0, 7, 0, 10, 15, 6, 1, 46, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 46, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, 6, 0, 10, 15, 7, 3, 46, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, 7, 0, 10, 15, 6, 1, 46, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 9, 12, 1, 46, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 21, 12, 1, 46, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 21, 0, 1, 46, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 46, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 9, 0, 1, 46, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 8, 3, 0, 331, 0, 10, 15, 6, 1, 25, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, 331, 0, 10, 15, 6, 1, 25, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 58, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 58, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 8, 3, 80, 0, 0, 10, 15, 8, 3, 58, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 21, 0, 1, 58, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 58, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 23, 10, 0, 0, 0, -1, 1, 8, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 24, 10, 0, 0, 0, -1, -1, 8, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 0, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 23, 10, 0, 0, 0, -1, 1, 10, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 24, 10, 0, 0, 0, -1, -1, 10, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 9, 12, 1, 2, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 25, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 9, 12, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 24, 3, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 24, 3, 0, 0, 0, 0, 2, 13, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 0, 17, 0, 1, 37, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 4, 5, 80, 0, 0, 0, 17, 0, 3, 37, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 0, 17, 0, 0, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 26, 5, 0, 0, 0, 0, 17, 0, 0, 2, 0 },
+ { 6, 9, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 18, 21, 5, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 1, 11, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 1, 12, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 10, 8, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 17, 8, 1, 2, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 5, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 5, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 8, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 0, 13, 1, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 0, 17, 0, 218, 5, -1, 0, 1, 5, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 228, 5, -1, 0, 1, 5, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 232, 5, -1, 0, 1, 5, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 222, 5, -1, 0, 1, 5, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 1, 0, 0, 224, 0, -1, 0, 1, 5, 0, 0, 4, 4, 27, 4, 1, 26, 0 },
+ { 20, 10, 1, 0, 0, -1, 0, 1, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 8, 17, 8, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 8, 27, 8, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 4, 5, 80, 0, 0, 0, 17, 8, 3, 37, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 6, 5, 0, 0, 0, 10, 8, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 5, 0, 0, 0, 10, 8, 8, 1, 2, 0 },
+ { 25, 10, 1, 0, 0, -1, 0, 6, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 8, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 17, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 17, 0, 0, 0, 17, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 5, 0, 0, 0, 0, 8, 8, 1, 34, 0 },
+ { 0, 17, 0, 8, 5, -1, 0, 1, 5, 204, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 8, 8, 0, 3, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 8, 8, 1, 34, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 17, 0, 0, 0, 8, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 5, 80, 0, 0, 0, 17, 8, 3, 34, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 6, 5, 0, 0, 0, 8, 8, 0, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 8, 8, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 8, 17, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 17, 0, 0, 8, 17, 8, 1, 35, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 8, 0, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 8, 8, 8, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 8, 8, 8, 1, 35, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 5, 17, 0, 0, 8, 8, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 5, 80, 0, 0, 8, 17, 8, 3, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 10, 17, 8, 1, 36, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 5, 0, 0, 0, 10, 17, 8, 1, 36, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, 0, 0, 10, 17, 8, 1, 36, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 5, 0, 0, 0, 10, 17, 8, 1, 36, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 10, 17, 8, 3, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 10, 17, 8, 2, 26, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 10, 17, 8, 1, 36, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, 0, 0, 10, 17, 8, 1, 36, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, 0, 0, 10, 17, 8, 1, 36, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 10, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 27, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 5, 0, 0, 0, 8, 8, 8, 1, 35, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 26, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 5, 80, 0, 0, 0, 17, 0, 3, 26, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 11, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 7, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 6, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 17, 0, 3, 26, 0 },
+ { 29, 0, 1, 0, 0, -1, 0, 1, 5, 80, 0, 14, 0, 17, 0, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 8, 17, 0, 3, 35, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 22, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 0, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 10, 17, 8, 1, 38, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 10, 8, 8, 1, 38, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 4, 5, 0, 0, 0, 0, 17, 0, 1, 38, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 6, 5, 0, 0, 0, 0, 17, 0, 1, 38, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 83, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 83, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 0, 1, 83, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 12, 1, 83, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 70, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 70, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 0, 1, 70, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 9, 12, 1, 70, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 12, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 70, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 5, 0 },
+ { 2, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 5, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 5, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 5, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 5, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 16, 3, 80, 0, 0, 10, 15, 6, 3, 5, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 17, 3, 0, 0, 4, 4, 27, 4, 1, 5, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 84, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 84, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 84, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 84, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 12, 1, 84, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 0, 1, 84, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 17, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 10, 3, 0, 332, 0, 10, 15, 7, 3, 3, 0 },
+ { 28, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 12, 3, 0, 333, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 12, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 12, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 13, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, 334, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 13, 3, 0, 335, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 336, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 337, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 338, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 18, 3, 0, 339, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 340, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 341, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, 342, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, 343, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 17, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 20, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 21, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 24, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, 344, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, 345, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 21, 3, 0, 346, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 23, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 23, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, 347, 0, 10, 15, 7, 3, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, 6, 0, 10, 15, 7, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 27, 3, 0, 7, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 27, 3, 0, 348, 0, 10, 15, 7, 3, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 24, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 13, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 3, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 59, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 59, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 59, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 8, 4, 27, 4, 1, 59, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 59, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 59, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 4, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 18, 0, 0, 0, 2, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 65, 0 },
+ { 18, 0, 0, 0, 4, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 65, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 65, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 24, 0, 1, 65, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 9, 12, 1, 65, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 8, 4, 27, 4, 1, 71, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 71, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 71, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 71, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 12, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 71, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 11, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 11, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 24, 0, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 11, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 11, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 14, 9, 1, 72, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 72, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 72, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 72, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 12, 1, 72, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 73, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 73, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 8, 4, 27, 4, 1, 73, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 73, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 73, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 85, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 8, 4, 27, 4, 1, 85, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 38, 8, 1, 85, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 85, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 11, 3, 0, 0, 4, 4, 41, 4, 1, 85, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 17, 0, 1, 85, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 0, 1, 85, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 12, 1, 85, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 21, 8, 1, 2, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 11, 3, 0, 0, 0, 16, 40, 9, 1, 85, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 44, 8, 1, 24, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 44, 4, 1, 24, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 44, 8, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 40, 8, 1, 77, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 10, 3, 0, 0, 4, 4, 27, 4, 1, 77, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 8, 4, 27, 4, 1, 77, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 21, 8, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 10, 3, 0, 0, 0, 16, 40, 9, 1, 77, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 17, 0, 1, 77, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 21, 12, 1, 77, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 8, 1, 24, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 8, 1, 24, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 0, 1, 24, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 4, 44, 4, 1, 24, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 8, 1, 79, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 11, 3, 0, 0, 4, 4, 44, 4, 1, 79, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 11, 3, 0, 0, 4, 4, 44, 4, 1, 79, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 8, 1, 79, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 44, 0, 1, 79, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 86, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 8, 4, 27, 4, 1, 86, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 86, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 21, 12, 1, 86, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 86, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 86, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 27, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, 349, 0, 10, 15, 6, 1, 3, 0 },
+ { 28, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 0, 1, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 16, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 6, 1, 4, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 23, 3, 80, 0, 0, 10, 15, 6, 3, 3, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 350, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 351, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 352, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 353, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 354, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 355, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 356, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 357, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 358, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 359, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 360, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 361, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 362, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 363, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 364, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 365, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 366, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 367, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 368, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 369, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 370, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 371, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 372, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 373, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 374, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 375, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 376, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 377, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 378, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 379, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 380, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 381, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 382, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 383, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 384, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 385, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 386, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 387, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 388, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 389, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 390, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 391, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 392, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 393, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 394, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 395, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 396, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 397, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 398, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 399, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 400, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 401, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 402, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 403, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 404, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 405, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 406, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 407, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 408, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 409, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 410, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 411, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 412, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 413, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 414, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 415, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 416, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 417, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 418, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 419, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 420, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 421, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 422, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 423, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 424, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 425, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 426, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 427, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 428, 0, 10, 15, 6, 3, 28, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 17, 3, 0, 429, 0, 10, 15, 6, 3, 28, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 86, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 8, 4, 27, 4, 1, 86, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 86, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 12, 1, 86, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 11, 3, 0, 0, 0, 16, 14, 9, 1, 86, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 2, 5, 17, 0, 12, 10, 29, 8, 1, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 2, 5, 17, 0, 13, 10, 30, 8, 1, 26, 0 },
+ { 11, 0, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 45, 0, 0, 0, 0 },
+ { 12, 0, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 5, 85, 0, 0, 0, 17, 8, 3, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 5, 85, 0, 0, 0, 17, 8, 3, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 6, 5, 85, 0, 0, 0, 17, 8, 3, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 5, 85, 0, 0, 0, 17, 8, 3, 37, 0 },
+ { 13, 0, 0, 0, 0, -1, 0, 0, 5, 0, 0, 0, 0, 17, 0, 0, 0, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 5, 85, 0, 0, 0, 17, 8, 3, 37, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 430, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 431, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 432, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 433, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 434, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 435, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 436, 0, 10, 15, 6, 3, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 437, 0, 10, 15, 6, 3, 6, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 438, 0, 10, 15, 6, 3, 6, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 439, 0, 10, 15, 6, 3, 6, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 440, 0, 10, 15, 6, 3, 6, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 3, 80, 441, 0, 10, 15, 6, 3, 6, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 4, 3, 85, 0, 0, 9, 16, 8, 3, 7, 0 },
+ { 0, 17, 0, 26, 5, -1, 0, 1, 3, 0, 0, 4, 4, 27, 4, 1, 7, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 1, 3, 85, 0, 0, 9, 16, 8, 3, 7, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 9, 16, 8, 3, 7, 0 },
+ { 26, 3, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 0, 15, 0, 3, 7, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 1, 3, 80, 0, 0, 10, 15, 8, 3, 8, 0 },
+ { 28, 13, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 22, 10, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 1, 13, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 13, 18, 0, 0, 0, -1, 0, 5, 3, 0, 0, 0, 0, 15, 0, 0, 0, 0 },
+ { 27, 13, 0, 0, 0, -1, 0, 6, 3, 80, 0, 0, 0, 13, 0, 3, 8, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 6, 0, 0, 0, 4, 4, 27, 4, 2, 1, 0 },
+ { 0, 17, 16, 0, 5, -1, 0, 6, 0, 0, 0, 4, 4, 27, 4, 2, 1, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 1, 11, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 1, 12, 0, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 14, 8, 11, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 8, 11, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 9, 12, 3, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 8, 5, 80, 0, 0, 0, 18, 0, 0, 2, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 1, 3, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 10, 3, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, 0, 4, 4, 7, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 17, 3, 0, 0, 4, 4, 7, 4, 1, 5, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 0, 2, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 11, 3, 2, 0 },
+ { 19, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 17, 17, 0, 3, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 6, 5, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 0, 7, 5, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, 0, 7, 5, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 15, 1, 11, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 11, 3, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 13, 1, 10, 0, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 15, 8, 11, 3, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 14, 8, 11, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 9, 12, 3, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 5, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 5, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 26, 3, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 20, 3, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 11, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 1, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -1, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 12, 0, 3, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 5, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 6, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 1, 3, 0, 0, 3, 6, 28, 4, 2, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 9, 12, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 12, 0, 3, 2, 0 },
+ { 25, 4, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 13, 17, 0, 3, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 1, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 1, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 26, 3, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 15, 1, 11, 3, 2, 0 },
+ { 20, 3, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 11, 3, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 13, 1, 10, 3, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 0, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 1, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 2, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 3, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 4, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 5, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 6, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 7, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 8, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 9, 0, 1, 1, 80, 0, 0, 16, 17, 9, 3, 2, 0 },
+ { 25, 6, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 14, 8, 11, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 15, 8, 11, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 2, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, -2, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 1, 1, 80, 1, 0, 10, 17, 7, 3, 3, 0 },
+ { 21, 10, 0, 0, 0, -1, 2, 1, 1, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -2, 1, 1, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 28, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 19, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 17, 17, 0, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 1, 1, 80, 2, 0, 10, 17, 6, 3, 3, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 6, 1, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 6, 1, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 0, 1, 12, 3, 2, 0 },
+ { 21, 10, 0, 0, 0, -1, 1, 1, 2, 80, 0, 0, 0, 0, 13, 3, 2, 0 },
+ { 22, 10, 0, 0, 0, -1, -1, 1, 2, 80, 0, 0, 0, 1, 13, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 0, 1, 11, 3, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 0, 8, 0, 3, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 8, 17, 8, 3, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 8, 8, 8, 3, 35, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 8, 8, 8, 3, 2, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 1, 2, 80, 0, 4, 4, 8, 4, 3, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 10, 17, 8, 2, 26, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 10, 17, 8, 3, 26, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 13, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 1, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 1, 2, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 10, 10, 0, 0, 5, -1, 0, 4, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 3, 3, 0, 0, 0, 0, 35, 0, 0, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 13, 18, 0, 0, 0, -1, 0, 1, 3, 0, 0, 0, 0, 15, 0, 0, 0, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 49, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 21, 0, 1, 2, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 4, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 4, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 4, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 4, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 4, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 4, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 15, 0, 1, 4, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 74, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 75, 0 },
+ { 5, 2, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 5, 3, 0, 0, 0, 10, 15, 8, 1, 39, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 39, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 5, 3, 0, 0, 0, 0, 15, 0, 1, 39, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 39, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 5, 3, 0, 0, 0, 10, 15, 8, 1, 40, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 5, 3, 0, 0, 0, 10, 15, 8, 1, 40, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 120, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 120, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 50, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 0, 21, 0, 1, 50, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 60, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 21, 0, 1, 60, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 60, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 5, 3, 0, 442, 0, 10, 15, 7, 3, 41, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 7, 3, 0, 442, 0, 10, 15, 7, 3, 41, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 5, 3, 0, 443, 0, 10, 15, 6, 1, 41, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 7, 3, 0, 443, 0, 10, 15, 6, 1, 41, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 51, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 7, 3, 0, 0, 0, 16, 14, 9, 1, 52, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 18, 3, 0, 442, 0, 10, 15, 7, 3, 136, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 18, 3, 0, 443, 0, 10, 15, 6, 1, 136, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 106, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 103, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 103, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 24, 3, 0, 444, 0, 10, 15, 7, 3, 161, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 24, 3, 0, 445, 0, 10, 15, 6, 1, 161, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 169, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 17, 0, 0, 10, 15, 8, 1, 169, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 110, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 24, 3, 80, 0, 0, 10, 15, 8, 3, 3, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 7, 3, 0, 0, 0, 10, 15, 8, 1, 53, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 87, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 0, 1, 87, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 87, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 118, 0 },
+ { 29, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 118, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 118, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 117, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 117, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 128, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 15, 0, 1, 128, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 64, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 15, 0, 1, 64, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 64, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 21, 0, 1, 64, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 10, 15, 8, 1, 76, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 10, 3, 0, 0, 0, 0, 15, 0, 1, 76, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 98, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 97, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 15, 0, 1, 97, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 10, 15, 8, 1, 61, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 61, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 61, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 61, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 61, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 61, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 61, 0 },
+ { 5, 1, 0, 0, 0, 1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 61, 0 },
+ { 5, 1, 0, 0, 0, 2, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 61, 0 },
+ { 5, 1, 0, 0, 0, 3, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 61, 0 },
+ { 5, 1, 0, 0, 0, 4, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 61, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 61, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 61, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 21, 0, 1, 61, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 21, 12, 1, 61, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 8, 3, 0, 0, 0, 0, 15, 0, 1, 61, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 88, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 88, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 88, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 116, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 116, 0 },
+ { 18, 1, 0, 0, 2, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 112, 0 },
+ { 18, 1, 0, 0, 3, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 112, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 112, 0 },
+ { 29, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 112, 0 },
+ { 18, 1, 0, 0, 4, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 112, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 112, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 112, 0 },
+ { 5, 1, 0, 0, 2, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 112, 0 },
+ { 5, 1, 0, 0, 3, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 112, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 0, 1, 112, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 18, 0, 1, 112, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 80, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 0, 1, 80, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 89, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 89, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 90, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 90, 0 },
+ { 18, 1, 0, 0, 2, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 121, 0 },
+ { 18, 1, 0, 0, 3, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 121, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 121, 0 },
+ { 5, 1, 0, 0, 3, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 121, 0 },
+ { 5, 1, 0, 0, 2, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 121, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 121, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 91, 0 },
+ { 14, 1, 0, 0, 0, -1, 0, 17, 3, 0, 85, 0, 10, 15, 7, 3, 130, 0 },
+ { 15, 1, 0, 0, 0, -1, 0, 17, 3, 0, 92, 0, 10, 15, 6, 1, 130, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 15, 0, 1, 130, 0 },
+ { 18, 13, 0, 0, 4, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 144, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 144, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 144, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 0, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 1, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 2, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 3, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 4, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 5, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 6, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 7, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 8, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 9, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 144, 0 },
+ { 3, 5, 0, 0, 0, 0, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 1, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 2, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 3, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 4, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 5, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 6, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 7, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 8, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 3, 5, 0, 0, 0, 9, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 164, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 164, 0 },
+ { 17, 1, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 164, 0 },
+ { 14, 1, 0, 0, 0, -1, 0, 27, 3, 0, 1, 0, 10, 15, 7, 3, 164, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 164, 0 },
+ { 20, 10, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 21, 0, 1, 164, 0 },
+ { 15, 1, 0, 0, 0, -1, 0, 27, 3, 0, 2, 0, 10, 15, 6, 1, 164, 0 },
+ { 26, 1, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 15, 0, 1, 164, 0 },
+ { 5, 5, 0, 0, 0, 1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 2, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 3, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 4, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 5, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 6, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 7, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 8, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, 9, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 5, 5, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 156, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 156, 0 },
+ { 20, 1, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 21, 0, 1, 156, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 8, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 8, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 147, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 147, 0 },
+ { 18, 13, 0, 0, 2, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 148, 0 },
+ { 18, 13, 0, 0, 3, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 148, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 148, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 148, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 148, 0 },
+ { 5, 13, 0, 0, 2, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 148, 0 },
+ { 5, 13, 0, 0, 3, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 148, 0 },
+ { 25, 13, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 12, 1, 148, 0 },
+ { 18, 1, 0, 0, 2, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 158, 0 },
+ { 18, 1, 0, 0, 3, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 158, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 158, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 158, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 15, 12, 1, 158, 0 },
+ { 18, 1, 0, 0, 2, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 153, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 153, 0 },
+ { 18, 1, 0, 0, 3, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 153, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 15, 0, 1, 153, 0 },
+ { 5, 1, 0, 0, 3, -1, 0, 23, 3, 0, 0, 0, 0, 15, 0, 1, 153, 0 },
+ { 5, 1, 0, 0, 2, -1, 0, 23, 3, 0, 0, 0, 0, 15, 0, 1, 153, 0 },
+ { 5, 1, 0, 0, 4, -1, 0, 23, 3, 0, 0, 0, 0, 15, 0, 1, 153, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 149, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 8, 4, 27, 4, 1, 94, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 12, 3, 0, 0, 4, 4, 27, 4, 1, 94, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 39, 8, 1, 94, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 38, 8, 1, 94, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 12, 3, 0, 0, 4, 4, 41, 4, 1, 94, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 21, 12, 1, 94, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 1, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 2, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 3, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 4, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 5, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 6, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 7, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 8, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, 9, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 17, 0, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 12, 3, 0, 0, 0, 16, 40, 9, 1, 94, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 94, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 38, 8, 1, 94, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 94, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, 0, 4, 4, 7, 4, 1, 94, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 92, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 8, 4, 27, 4, 1, 92, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 92, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 17, 0, 0, 10, 15, 8, 1, 92, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 11, 3, 0, 0, 4, 4, 27, 4, 1, 92, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 11, 3, 204, 0, 4, 4, 27, 4, 1, 92, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 15, 0, 1, 92, 0 },
+ { 10, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 7, 16, 14, 9, 0, 92, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 0, 21, 12, 1, 92, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 92, 0 },
+ { 10, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 7, 16, 14, 9, 0, 92, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 101, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 96, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 96, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 204, 0, 4, 4, 27, 4, 1, 96, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 96, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 8, 4, 27, 4, 1, 96, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 17, 0, 4, 4, 27, 4, 1, 96, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 96, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 21, 0, 1, 96, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 21, 12, 1, 96, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 96, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 8, 4, 27, 4, 1, 96, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 96, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 111, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 111, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 111, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 24, 0, 1, 111, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 100, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 8, 4, 27, 4, 1, 100, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 100, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 100, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 7, 10, 15, 8, 1, 100, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 21, 12, 1, 100, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 15, 0, 1, 100, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 21, 0, 1, 100, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, 0, 4, 4, 27, 4, 1, 100, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 17, 3, 0, 0, 4, 4, 27, 4, 1, 100, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 12, 1, 100, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 8, 4, 27, 4, 1, 100, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 100, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 100, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 24, 0, 1, 100, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 100, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 21, 0, 1, 100, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 21, 12, 1, 100, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 20, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 109, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 8, 4, 27, 4, 1, 109, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 109, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 109, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 109, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 109, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 109, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 109, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 10, 15, 8, 1, 109, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 109, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 129, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 21, 12, 1, 129, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 123, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 123, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 8, 4, 27, 4, 1, 123, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 123, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 123, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, 0, 4, 4, 27, 4, 1, 107, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 107, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 8, 4, 27, 4, 1, 107, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 38, 8, 1, 107, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 107, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 21, 8, 1, 107, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 204, 0, 4, 4, 27, 4, 1, 107, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 17, 0, 8, 4, 27, 4, 1, 107, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 16, 3, 0, 0, 4, 4, 41, 4, 1, 107, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 40, 8, 1, 107, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 40, 8, 1, 107, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 107, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 40, 8, 1, 170, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 17, 0, 0, 10, 40, 8, 1, 170, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 38, 8, 1, 170, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 17, 8, 1, 170, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 27, 3, 204, 0, 4, 4, 27, 4, 1, 170, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 8, 4, 27, 4, 1, 170, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 27, 3, 204, 0, 4, 4, 27, 4, 1, 170, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 170, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 27, 3, 221, 0, 4, 4, 27, 4, 1, 170, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 170, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 170, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 27, 3, 0, 0, 4, 4, 41, 4, 1, 170, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 7, 10, 39, 8, 1, 170, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 17, 12, 1, 170, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 17, 0, 1, 170, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 10, 15, 8, 1, 135, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 8, 4, 27, 4, 1, 135, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 135, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 135, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 135, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 21, 12, 1, 135, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 21, 0, 1, 135, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 15, 0, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 135, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 21, 0, 1, 135, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 135, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 135, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 135, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 124, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 204, 0, 4, 4, 27, 4, 1, 124, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 8, 4, 27, 4, 1, 124, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 124, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 204, 0, 4, 4, 27, 4, 1, 124, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 17, 0, 8, 4, 27, 4, 1, 124, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 124, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 124, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 124, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 122, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 204, 0, 4, 4, 27, 4, 1, 122, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 8, 4, 27, 4, 1, 122, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 122, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 17, 0, 8, 4, 27, 4, 1, 122, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 122, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 122, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 24, 0, 1, 122, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 122, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 9, 0, 1, 122, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 122, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 21, 12, 1, 122, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 122, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, 0, 4, 4, 27, 4, 1, 122, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 114, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 8, 4, 27, 4, 1, 114, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 114, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 114, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 114, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 114, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 24, 0, 1, 33, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 102, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 102, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 8, 4, 27, 4, 1, 102, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 102, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 102, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 102, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 15, 0, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 13, 3, 0, 0, 0, 16, 14, 9, 1, 102, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 24, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 44, 8, 1, 126, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 44, 8, 1, 126, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, 0, 4, 4, 44, 4, 1, 126, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 8, 4, 44, 4, 1, 126, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 4, 44, 4, 1, 126, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 17, 3, 0, 0, 4, 4, 44, 4, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 17, 3, 0, 0, 0, 16, 14, 9, 1, 126, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 44, 0, 1, 126, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 21, 12, 1, 126, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 44, 0, 1, 126, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 44, 8, 1, 126, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 142, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 8, 4, 27, 4, 1, 142, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 142, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 142, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 142, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 142, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 16, 3, 0, 1, 0, 10, 15, 7, 3, 125, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 16, 3, 0, 2, 0, 10, 15, 6, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 125, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 125, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 125, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 38, 8, 1, 154, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 23, 3, 204, 0, 4, 4, 27, 4, 1, 154, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 8, 4, 27, 4, 1, 154, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 23, 3, 17, 0, 8, 4, 27, 4, 1, 154, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 154, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 154, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 23, 3, 0, 0, 4, 4, 41, 4, 1, 154, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 7, 10, 39, 8, 1, 154, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 23, 3, 0, 0, 4, 4, 27, 4, 1, 154, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 21, 12, 1, 154, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 0, 21, 0, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 23, 3, 0, 0, 0, 16, 40, 9, 1, 154, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 150, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 8, 4, 27, 4, 1, 150, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 21, 3, 0, 0, 4, 4, 27, 4, 1, 150, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 21, 3, 0, 0, 4, 4, 27, 4, 1, 150, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 24, 0, 1, 150, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 141, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 141, 0 },
+ { 0, 0, 0, 0, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 141, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 141, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 8, 4, 27, 4, 1, 141, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 7, 10, 15, 8, 1, 141, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 24, 0, 1, 141, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 15, 0, 1, 141, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 21, 0, 1, 141, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 21, 12, 1, 141, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 140, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 140, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 8, 4, 27, 4, 1, 140, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 7, 10, 15, 8, 1, 140, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 7, 10, 15, 8, 1, 140, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 140, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 21, 0, 1, 140, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 21, 12, 1, 140, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 140, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 0, 24, 0, 1, 140, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 29, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 119, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 0, 24, 0, 1, 11, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 168, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 15, 0, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 168, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 10, 15, 8, 1, 133, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 8, 4, 27, 4, 1, 133, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 133, 0 },
+ { 0, 0, 0, 9, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 133, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 21, 12, 1, 133, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 21, 0, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 133, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 15, 0, 1, 133, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 24, 0, 1, 134, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 9, 0, 1, 134, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 10, 15, 8, 1, 134, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 134, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 18, 3, 0, 0, 8, 4, 27, 4, 1, 134, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 0, 10, 15, 8, 1, 138, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 138, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 138, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 19, 3, 0, 0, 4, 4, 27, 4, 1, 138, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 3, 0, 0, 7, 10, 15, 8, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 19, 3, 0, 0, 0, 16, 14, 9, 1, 138, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 15, 8, 1, 143, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 8, 4, 27, 4, 1, 143, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 143, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 20, 3, 0, 0, 0, 16, 14, 9, 1, 143, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 40, 8, 1, 145, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 10, 21, 8, 1, 145, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 20, 3, 0, 0, 4, 4, 27, 4, 1, 145, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 8, 4, 27, 4, 1, 145, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 21, 12, 1, 145, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 162, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 7, 10, 39, 8, 1, 162, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 8, 4, 27, 4, 1, 162, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 10, 38, 8, 1, 162, 0 },
+ { 1, 0, 0, 9, 0, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 162, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 25, 3, 0, 0, 4, 4, 41, 4, 1, 162, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 0, 21, 12, 1, 162, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 0, 17, 0, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 25, 3, 0, 0, 0, 16, 40, 9, 1, 162, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 162, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 3, 0, 0, 0, 10, 15, 8, 1, 83, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 15, 0, 1, 16, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 15, 0, 1, 16, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 13, 0, 1, 16, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 21, 0, 1, 16, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 63, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 63, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 63, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 10, 15, 8, 1, 63, 0 },
+ { 4, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 63, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 9, 3, 0, 0, 0, 0, 21, 0, 1, 63, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 0, 1, 63, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 157, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 15, 0, 1, 157, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 15, 8, 1, 81, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 0, 8, 1, 81, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 11, 3, 0, 0, 0, 10, 1, 8, 1, 81, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 10, 0, 8, 1, 81, 0 },
+ { 10, 0, 0, 0, 5, -1, 0, 21, 3, 0, 0, 3, 6, 7, 4, 0, 81, 0 },
+ { 10, 0, 0, 0, 5, -1, 0, 21, 3, 0, 0, 3, 6, 0, 4, 0, 81, 0 },
+ { 10, 0, 0, 0, 5, -1, 0, 21, 3, 0, 0, 3, 6, 1, 4, 0, 81, 0 },
+ { 10, 0, 0, 0, 5, -1, 0, 25, 3, 0, 0, 3, 6, 7, 4, 0, 81, 0 },
+ { 10, 0, 0, 0, 5, -1, 0, 25, 3, 0, 0, 3, 6, 0, 4, 0, 81, 0 },
+ { 10, 0, 0, 0, 5, -1, 0, 25, 3, 0, 0, 3, 6, 1, 4, 0, 81, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 81, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 10, 15, 8, 1, 81, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 81, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 15, 8, 1, 127, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 0, 8, 1, 127, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 10, 1, 8, 1, 127, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 40, 8, 1, 165, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 27, 3, 204, 0, 4, 4, 27, 4, 1, 165, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 27, 3, 221, 0, 4, 4, 27, 4, 1, 165, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 8, 4, 27, 4, 1, 165, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 165, 0 },
+ { 0, 17, 0, 9, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, 0, 0, 16, 40, 9, 1, 165, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 10, 15, 8, 1, 84, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 115, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 115, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 24, 3, 0, 0, 0, 16, 14, 9, 1, 159, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 104, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 104, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 104, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 108, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 108, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 108, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 0, 1, 108, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 108, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 108, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 16, 3, 0, 0, 0, 16, 14, 9, 1, 108, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 108, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 166, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 166, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 10, 10, 15, 8, 1, 166, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 204, 0, 10, 10, 15, 8, 1, 166, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 221, 0, 10, 10, 15, 8, 1, 166, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 17, 0, 10, 10, 15, 8, 1, 166, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 15, 0, 1, 166, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 21, 12, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 166, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 20, 3, 0, 1, 0, 10, 15, 7, 3, 146, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 20, 3, 0, 2, 0, 10, 15, 6, 1, 146, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 146, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 21, 0, 1, 146, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 21, 12, 1, 146, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 146, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 99, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 99, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 21, 3, 0, 0, 4, 4, 27, 4, 1, 99, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 8, 4, 27, 4, 1, 99, 0 },
+ { 1, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 8, 4, 27, 4, 1, 99, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 13, 3, 0, 0, 4, 4, 27, 4, 1, 99, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 10, 15, 8, 1, 99, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 18, 5, 0, 0, 0, 10, 8, 8, 1, 137, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 19, 5, 0, 0, 0, 10, 8, 8, 1, 139, 0 },
+ { 25, 10, 0, 0, 0, -1, 0, 21, 5, 0, 0, 0, 0, 8, 0, 1, 37, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 21, 5, 0, 0, 0, 10, 8, 8, 1, 37, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 23, 5, 0, 0, 4, 4, 7, 4, 1, 155, 0 },
+ { 1, 0, 0, 6, 0, -1, 0, 23, 5, 0, 0, 4, 4, 27, 4, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 18, 5, 0, 0, 0, 0, 17, 8, 1, 137, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 20, 5, 0, 0, 0, 0, 17, 8, 1, 137, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 5, 0, 0, 0, 0, 17, 8, 1, 137, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, 0, 0, 0, 17, 8, 1, 137, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 23, 5, 0, 0, 0, 0, 15, 8, 1, 155, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 5, 0, 0, 0, 0, 15, 8, 1, 155, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 24, 5, 0, 0, 0, 8, 15, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, 0, 0, 8, 17, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, 0, 0, 0, 17, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, 0, 0, 0, 17, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 5, 0, 0, 0, 0, 17, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 5, 0, 0, 0, 8, 17, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 5, 0, 0, 0, 0, 8, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 5, 0, 0, 0, 0, 8, 8, 1, 34, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 5, 0, 0, 0, 8, 8, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 5, 0, 0, 0, 8, 8, 8, 1, 35, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 19, 5, 0, 0, 0, 0, 17, 8, 1, 139, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 105, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 105, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 105, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 105, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 21, 12, 1, 105, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 16, 3, 0, 0, 3, 6, 27, 4, 2, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 27, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 0, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 1, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 2, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 3, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 4, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 5, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 6, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 7, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 8, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 9, 0, 27, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 5, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 5, 3, 85, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 1, 0, 0, 216, 0, -1, 0, 5, 3, 0, 0, 4, 4, 27, 4, 1, 2, 0 },
+ { 0, 17, 0, 1, 5, -1, 0, 5, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 1, 0, 0, 226, 0, -1, 0, 5, 3, 0, 0, 4, 4, 27, 4, 1, 2, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 5, 3, 0, 0, 3, 6, 27, 4, 2, 2, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 5, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 5, 3, 0, 0, 4, 4, 27, 4, 1, 1, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 8, 3, 0, 0, 4, 4, 27, 4, 1, 4, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 9, 5, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 5, 0, 0, 0, 0, -1, 0, 20, 5, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 5, 3, 80, 0, 0, 10, 15, 7, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 5, 3, 80, 0, 0, 10, 15, 6, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 7, 3, 80, 0, 0, 10, 15, 6, 3, 2, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 5, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 14, 0, 0, 0, 0, -1, 0, 9, 3, 80, 0, 0, 10, 15, 7, 3, 2, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 9, 3, 80, 0, 0, 10, 15, 6, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 0, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 1, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 2, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 3, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 4, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 5, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 6, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 7, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 8, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 9, 0, 5, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 15, 0, 1, 131, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 17, 3, 0, 0, 4, 4, 27, 4, 1, 131, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 21, 0, 1, 131, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 21, 12, 1, 131, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 17, 3, 0, 0, 0, 0, 15, 0, 1, 131, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 3, 0 },
+ { 15, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 10, 15, 6, 1, 3, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 57, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 25, 3, 80, 0, 0, 10, 15, 6, 3, 5, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 5, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 151, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 21, 3, 0, 0, 4, 4, 27, 4, 1, 151, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 151, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 15, 0, 1, 151, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 160, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 24, 3, 0, 0, 4, 4, 27, 4, 1, 160, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 152, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 21, 3, 0, 0, 4, 4, 27, 4, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 21, 3, 0, 0, 0, 16, 14, 9, 1, 152, 0 },
+ { 27, 4, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 12, 0, 1, 152, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 10, 15, 8, 1, 163, 0 },
+ { 17, 0, 0, 0, 0, -1, 0, 25, 3, 0, 0, 0, 10, 15, 8, 1, 163, 0 },
+ { 0, 17, 0, 232, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 163, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 163, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 25, 3, 0, 0, 4, 4, 27, 4, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 25, 3, 0, 0, 0, 16, 14, 9, 1, 163, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 10, 15, 8, 1, 167, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 167, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 27, 3, 0, 0, 4, 4, 27, 4, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 1, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 2, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 3, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 4, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 5, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 6, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 7, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 8, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 3, 0, 0, 0, 0, 9, 0, 27, 3, 0, 0, 0, 16, 14, 9, 1, 167, 0 },
+ { 25, 0, 0, 0, 0, -1, 0, 27, 3, 0, 0, 0, 0, 15, 0, 1, 167, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 24, 3, 0, 0, 0, 10, 15, 8, 1, 27, 0 },
+ { 18, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 10, 15, 8, 1, 113, 0 },
+ { 5, 1, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 113, 0 },
+ { 0, 17, 0, 220, 5, -1, 0, 16, 3, 0, 0, 4, 4, 27, 4, 1, 113, 0 },
+ { 14, 1, 0, 0, 2, -1, 0, 18, 3, 0, 446, 0, 10, 15, 7, 3, 132, 0 },
+ { 15, 1, 0, 0, 2, -1, 0, 18, 3, 0, 447, 0, 10, 15, 6, 1, 132, 0 },
+ { 0, 17, 0, 230, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 132, 0 },
+ { 0, 17, 0, 7, 5, -1, 0, 18, 3, 0, 0, 4, 4, 27, 4, 1, 132, 0 },
+ { 17, 1, 0, 0, 5, -1, 0, 21, 3, 0, 0, 0, 10, 15, 8, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 0, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 1, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 2, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 3, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 4, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 5, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 6, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 7, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 8, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 3, 1, 0, 0, 0, 9, 0, 18, 3, 0, 0, 0, 16, 14, 9, 1, 132, 0 },
+ { 25, 1, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 0, 0, 1, 132, 0 },
+ { 5, 13, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 13, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 27, 13, 0, 0, 0, -1, 0, 20, 3, 0, 0, 0, 0, 13, 0, 1, 2, 0 },
+ { 5, 13, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 13, 0, 0, 0, -1, 0, 21, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 18, 13, 0, 0, 0, -1, 0, 13, 3, 80, 0, 0, 10, 15, 8, 3, 8, 0 },
+ { 26, 10, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 15, 0, 1, 8, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 10, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 13, 0, 0, 0, 0, -1, 0, 0, 3, 0, 0, 14, 0, 17, 0, 0, 0, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 5, 2, 0, 0, 0, 0, 0, 11, 0, 80, 0, 0, 0, 15, 0, 0, 2, 0 },
+ { 5, 2, 0, 0, 0, 0, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 1, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 2, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 3, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 4, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 5, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 6, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 7, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 8, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 2, 0, 0, 0, 9, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 5, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 23, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 20, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 12, 0, 80, 0, 0, 10, 15, 7, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 0, 80, 0, 0, 10, 15, 7, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 12, 0, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 12, 0, 0, 0, 0, 10, 15, 7, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 0, 0, 0, 0, 10, 15, 7, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 13, 3, 80, 0, 0, 0, 15, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 21, 3, 80, 0, 14, 0, 15, 0, 3, 2, 0 },
+ { 29, 0, 1, 0, 0, -1, 0, 12, 0, 0, 0, 14, 10, 15, 7, 1, 2, 0 },
+ { 29, 0, 1, 0, 0, -1, 0, 11, 0, 0, 0, 14, 10, 15, 7, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 3, 0, 0, -1, 0, 12, 5, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 12, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 18, 0, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 0, 19, 0, 0, -1, 0, 12, 3, 0, 0, 6, 7, 34, 0, 1, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 11, 5, 80, 0, 0, 0, 17, 0, 3, 34, 0 },
+ { 29, 0, 3, 0, 0, -1, 0, 12, 5, 80, 0, 14, 0, 17, 0, 3, 2, 0 },
+ { 29, 0, 1, 0, 0, -1, 0, 12, 5, 80, 0, 14, 0, 17, 0, 3, 2, 0 },
+ { 29, 0, 3, 0, 0, -1, 0, 11, 5, 80, 0, 14, 0, 17, 0, 3, 2, 0 },
+ { 29, 0, 0, 0, 0, -1, 0, 18, 5, 80, 0, 0, 0, 17, 0, 3, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 19, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 1, 0, 0, -1, 0, 16, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 17, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 16, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 9, 0, 0, -1, 0, 16, 3, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 28, 10, 23, 0, 0, -1, 0, 17, 5, 0, 0, 4, 4, 37, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 13, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 17, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 18, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 16, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 18, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 13, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 3, 13, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 16, 3, 0, 0, 0, 0, 8, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 19, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 21, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 23, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 25, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 24, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 19, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 20, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 12, 3, 0, 0, 0, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 25, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 20, 3, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 13, 0, 0, 0, 0, -1, 0, 0, 3, 0, 0, 14, 0, 15, 0, 0, 0, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 27, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 23, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 21, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 17, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 19, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 18, 3, 0, 0, 0, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 19, 0, 0, -1, 0, 20, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 20, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 0, 0, 0, -1, 0, 21, 3, 0, 0, 14, 0, 15, 0, 1, 2, 0 },
+ { 29, 10, 3, 0, 0, -1, 0, 27, 5, 0, 0, 14, 0, 17, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 24, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 29, 10, 11, 0, 0, -1, 0, 25, 5, 0, 0, 14, 0, 36, 0, 1, 2, 0 },
+ { 3, 2, 0, 0, 0, 0, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 1, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 2, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 3, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 4, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 5, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 6, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 7, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 8, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 3, 2, 0, 0, 0, 9, 0, 23, 3, 80, 0, 0, 16, 14, 9, 3, 2, 0 },
+ { 13, 18, 0, 0, 0, -1, 0, 2, 3, 0, 0, 0, 0, 15, 0, 0, 0, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 5, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 25, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 12, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 26, 5, 0, 0, 0, 0, 17, 8, 1, 37, 0 },
+ { 18, 0, 0, 0, 0, -1, 0, 5, 5, 85, 0, 0, 0, 17, 8, 3, 37, 0 },
+ { 10, 18, 0, 0, 5, -1, 0, 5, 3, 0, 0, 3, 6, 27, 4, 0, 2, 0 },
+ { 10, 18, 16, 0, 5, -1, 0, 5, 3, 0, 0, 4, 4, 27, 4, 0, 2, 0 },
+ { 0, 17, 0, 0, 5, -1, 0, 7, 0, 0, 0, 4, 4, 27, 4, 2, 1, 0 },
+ { 12, 0, 0, 0, 0, -1, 0, 2, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0 }
};
Q_DECL_CONST_FUNCTION static Q_ALWAYS_INLINE
@@ -10852,7 +11303,7 @@ const Properties * QT_FASTCALL properties(char32_t ucs4) noexcept
QSpan<const CaseConversion, NumCases> QT_FASTCALL caseConversion(char32_t ucs4) noexcept
{
- return qGetProp(ucs4)->cases;
+ return caseConversions[qGetProp(ucs4)->caseIndex];
}
Q_CORE_EXPORT GraphemeBreakClass QT_FASTCALL graphemeBreakClass(char32_t ucs4) noexcept
diff --git a/src/corelib/text/qunicodetables_p.h b/src/corelib/text/qunicodetables_p.h
index ac624dba789..8ba9e41437b 100644
--- a/src/corelib/text/qunicodetables_p.h
+++ b/src/corelib/text/qunicodetables_p.h
@@ -57,13 +57,14 @@ struct Properties {
ushort unicodeVersion : 5; /* 5 used */
ushort eastAsianWidth : 3; /* 3 used */
ushort nfQuickCheck : 8;
- std::array<CaseConversion, NumCases> cases;
+ ushort caseIndex : 16; /* 9 used */
ushort graphemeBreakClass : 5; /* 5 used */
ushort wordBreakClass : 5; /* 5 used */
ushort lineBreakClass : 6; /* 6 used */
ushort sentenceBreakClass : 4; /* 4 used */
ushort idnaStatus : 4; /* 3 used */
ushort script : 8;
+ ushort reserved : 16; /* makes sizeof a nice round 16 bytes */
};
Q_DECL_CONST_FUNCTION
@@ -72,7 +73,7 @@ Q_CORE_EXPORT const Properties * QT_FASTCALL properties(char32_t ucs4) noexcept;
Q_DECL_CONST_FUNCTION Q_CORE_EXPORT
QSpan<const CaseConversion, NumCases> QT_FASTCALL caseConversion(char32_t ucs4) noexcept;
-static_assert(sizeof(Properties) == 20);
+static_assert(sizeof(Properties) == 16);
enum class EastAsianWidth : unsigned int {
A,
diff --git a/src/corelib/text/qunicodetools.cpp b/src/corelib/text/qunicodetools.cpp
index 2d0b65fcc76..56fa41c51ab 100644
--- a/src/corelib/text/qunicodetools.cpp
+++ b/src/corelib/text/qunicodetools.cpp
@@ -4,6 +4,7 @@
#include "qunicodetools_p.h"
+#include <QtCore/private/qstringiterator_p.h>
#include "qunicodetables_p.h"
#include "qvarlengtharray.h"
#if QT_CONFIG(library)
@@ -122,16 +123,10 @@ static void getGraphemeBreaks(const char16_t *string, qsizetype len, QCharAttrib
{
QUnicodeTables::GraphemeBreakClass lcls = QUnicodeTables::GraphemeBreak_LF; // to meet GB1
GB::State state = GB::State::Normal;
- for (qsizetype i = 0; i != len; ++i) {
- qsizetype pos = i;
- char32_t ucs4 = string[i];
- if (QChar::isHighSurrogate(ucs4) && i + 1 != len) {
- ushort low = string[i + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ++i;
- }
- }
+ QStringIterator it(QStringView{string, len});
+ while (it.hasNext()) {
+ const qsizetype pos = it.index();
+ const char32_t ucs4 = it.nextOrRawCodeUnit();
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4);
QUnicodeTables::GraphemeBreakClass cls = (QUnicodeTables::GraphemeBreakClass) prop->graphemeBreakClass;
@@ -247,18 +242,12 @@ static void getWordBreaks(const char16_t *string, qsizetype len, QCharAttributes
QUnicodeTables::WordBreakClass cls = QUnicodeTables::WordBreak_LF; // to meet WB1
auto real_cls = cls; // Unaffected by WB4
- for (qsizetype i = 0; i != len; ++i) {
- qsizetype pos = i;
- char32_t ucs4 = string[i];
- if (QChar::isHighSurrogate(ucs4) && i + 1 != len) {
- ushort low = string[i + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ++i;
- }
- }
+ QStringIterator it(QStringView{string, len});
+ while (it.hasNext()) {
+ const qsizetype pos = it.index();
+ const char32_t ucs4 = it.nextOrRawCodeUnit();
- const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4);
+ const auto prop = QUnicodeTables::properties(ucs4);
QUnicodeTables::WordBreakClass ncls = (QUnicodeTables::WordBreakClass) prop->wordBreakClass;
if (qt_initcharattributes_default_algorithm_only) {
// as of Unicode 5.1, some punctuation marks were mapped to MidLetter and MidNumLet
@@ -299,17 +288,10 @@ static void getWordBreaks(const char16_t *string, qsizetype len, QCharAttributes
break;
case WB::Lookup:
case WB::LookupW:
- for (qsizetype lookahead = i + 1; lookahead < len; ++lookahead) {
- ucs4 = string[lookahead];
- if (QChar::isHighSurrogate(ucs4) && lookahead + 1 != len) {
- ushort low = string[lookahead + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ++lookahead;
- }
- }
+ for (auto lookahead = it; lookahead.hasNext(); /**/) {
+ const char32_t ucs4 = lookahead.nextOrRawCodeUnit();
- prop = QUnicodeTables::properties(ucs4);
+ const auto prop = QUnicodeTables::properties(ucs4);
QUnicodeTables::WordBreakClass tcls = (QUnicodeTables::WordBreakClass) prop->wordBreakClass;
if (Q_UNLIKELY(tcls == QUnicodeTables::WordBreak_Extend || tcls == QUnicodeTables::WordBreak_ZWJ || tcls == QUnicodeTables::WordBreak_Format)) {
@@ -319,7 +301,7 @@ static void getWordBreaks(const char16_t *string, qsizetype len, QCharAttributes
if (Q_LIKELY(tcls == cls || (action == WB::LookupW && (tcls == QUnicodeTables::WordBreak_HebrewLetter
|| tcls == QUnicodeTables::WordBreak_ALetter)))) {
- i = lookahead;
+ it = lookahead;
ncls = tcls;
action = WB::NoBreak;
}
@@ -406,35 +388,23 @@ static const uchar breakTable[BAfter + 1][QUnicodeTables::NumSentenceBreakClasse
static void getSentenceBreaks(const char16_t *string, qsizetype len, QCharAttributes *attributes)
{
uchar state = SB::BAfter; // to meet SB1
- for (qsizetype i = 0; i != len; ++i) {
- qsizetype pos = i;
- char32_t ucs4 = string[i];
- if (QChar::isHighSurrogate(ucs4) && i + 1 != len) {
- ushort low = string[i + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ++i;
- }
- }
- const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4);
+ QStringIterator it(QStringView{string, len});
+ while (it.hasNext()) {
+ const qsizetype pos = it.index();
+ const char32_t ucs4 = it.nextOrRawCodeUnit();
+
+ const auto prop = QUnicodeTables::properties(ucs4);
QUnicodeTables::SentenceBreakClass ncls = (QUnicodeTables::SentenceBreakClass) prop->sentenceBreakClass;
Q_ASSERT(state <= SB::BAfter);
state = SB::breakTable[state][ncls];
if (Q_UNLIKELY(state == SB::Lookup)) { // SB8
state = SB::Break;
- for (qsizetype lookahead = i + 1; lookahead < len; ++lookahead) {
- ucs4 = string[lookahead];
- if (QChar::isHighSurrogate(ucs4) && lookahead + 1 != len) {
- ushort low = string[lookahead + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ++lookahead;
- }
- }
+ for (auto lookahead = it; lookahead.hasNext(); /**/) {
+ const char32_t ucs4 = lookahead.nextOrRawCodeUnit();
- prop = QUnicodeTables::properties(ucs4);
+ const auto prop = QUnicodeTables::properties(ucs4);
QUnicodeTables::SentenceBreakClass tcls = (QUnicodeTables::SentenceBreakClass) prop->sentenceBreakClass;
switch (tcls) {
case QUnicodeTables::SentenceBreak_Any:
@@ -445,7 +415,7 @@ static void getSentenceBreaks(const char16_t *string, qsizetype len, QCharAttrib
case QUnicodeTables::SentenceBreak_Close:
continue;
case QUnicodeTables::SentenceBreak_Lower:
- i = lookahead;
+ it = lookahead;
state = SB::Initial;
break;
default:
@@ -772,18 +742,19 @@ static void getLineBreaks(const char16_t *string, qsizetype len, QCharAttributes
// even after spaces.
// × [\p{Pf}&QU] ( SP | GL | WJ | CL | QU | CP | EX | IS
// | SY | BK | CR | LF | NL | ZW | eot)
- auto nncls = QUnicodeTables::LineBreak_LF;
-
- if (i + 1 < len) {
+ const auto nncls = [&] {
+ if (i + 1 >= len)
+ return QUnicodeTables::LineBreak_LF;
char32_t c = string[i + 1];
if (QChar::isHighSurrogate(c) && i + 2 < len) {
ushort low = string[i + 2];
if (QChar::isLowSurrogate(low))
c = QChar::surrogateToUcs4(c, low);
+ else
+ return QUnicodeTables::LineBreak_SG; // all surrogates
}
- nncls = QUnicodeTables::LineBreakClass(
- QUnicodeTables::properties(c)->lineBreakClass);
- }
+ return QUnicodeTables::lineBreakClass(c);
+ }();
constexpr QUnicodeTables::LineBreakClass lb15b[] = {
QUnicodeTables::LineBreak_SP, QUnicodeTables::LineBreak_GL,
@@ -873,14 +844,17 @@ static void getLineBreaks(const char16_t *string, qsizetype len, QCharAttributes
// ‘subtract .5’.
if (Q_UNLIKELY(lcls == QUnicodeTables::LineBreak_SP)) {
if (i + 1 < len) {
+ constexpr char32_t Invalid = ~U'\0';
char32_t ch = string[i + 1];
if (QChar::isHighSurrogate(ch) && i + 2 < len) {
ushort low = string[i + 2];
if (QChar::isLowSurrogate(low))
ch = QChar::surrogateToUcs4(ch, low);
+ else
+ ch = Invalid;
}
- if (QUnicodeTables::properties(ch)->lineBreakClass
- == QUnicodeTables::LineBreak_NU) {
+ if (ch != Invalid // surrogates won't match (ensured by util/unicode)
+ && QUnicodeTables::lineBreakClass(ch) == QUnicodeTables::LineBreak_NU) {
attributes[pos].lineBreak = true;
goto next;
}
@@ -1123,18 +1097,10 @@ static void getLineBreaks(const char16_t *string, qsizetype len, QCharAttributes
static void getWhiteSpaces(const char16_t *string, qsizetype len, QCharAttributes *attributes)
{
- for (qsizetype i = 0; i != len; ++i) {
- const auto pos = i;
- uint ucs4 = string[i];
- if (QChar::isHighSurrogate(ucs4) && i + 1 != len) {
- ushort low = string[i + 1];
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ++i;
- }
- }
-
- if (Q_UNLIKELY(QChar::isSpace(ucs4)))
+ QStringIterator it(QStringView{string, len});
+ while (it.hasNext()) {
+ const auto pos = it.index();
+ if (Q_UNLIKELY(QChar::isSpace(it.nextOrRawCodeUnit())))
attributes[pos].whiteSpace = true;
}
}
@@ -2821,18 +2787,12 @@ Q_CORE_EXPORT void initCharAttributes(QStringView string,
Q_CORE_EXPORT void initScripts(QStringView string, ScriptItemArray *scripts)
{
qsizetype sor = 0;
- qsizetype eor = 0;
QChar::Script script = QChar::Script_Common;
- for (qsizetype i = 0; i < string.size(); ++i, eor = i) {
- char32_t ucs4 = string[i].unicode();
- if (QChar::isHighSurrogate(ucs4) && i + 1 < string.size()) {
- ushort low = string[i + 1].unicode();
- if (QChar::isLowSurrogate(low)) {
- ucs4 = QChar::surrogateToUcs4(ucs4, low);
- ++i;
- }
- }
+ QStringIterator it(string);
+ while (it.hasNext()) {
+ const auto eor = it.index();
+ const char32_t ucs4 = it.nextOrRawCodeUnit();
const QUnicodeTables::Properties *prop = QUnicodeTables::properties(ucs4);
@@ -2865,7 +2825,6 @@ Q_CORE_EXPORT void initScripts(QStringView string, ScriptItemArray *scripts)
}
Q_ASSERT(script >= QChar::Script_Common);
- Q_ASSERT(eor == string.size());
scripts->append(ScriptItem{sor, script});
}
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index d0e61a1cf6c..bcb92b384ae 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -316,6 +316,19 @@
*/
/*!
+ \fn template <typename T> void QAtomicInteger<T>::refRelaxed()
+ \internal
+ Atomically increments the value of this QAtomicInteger.
+
+ In contrast to ref(), this uses relaxed semantics, which is
+ all that is needed for reference counting (together with deref's
+ acquire-release semantics).
+ It also doesn't return anything.
+
+ \sa deref(), operator++()
+*/
+
+/*!
\fn template <typename T> T QAtomicInteger<T>::operator++()
\since 5.3
diff --git a/src/corelib/thread/qatomic.h b/src/corelib/thread/qatomic.h
index 4fa4fcd2ff5..2e629735128 100644
--- a/src/corelib/thread/qatomic.h
+++ b/src/corelib/thread/qatomic.h
@@ -46,6 +46,7 @@ public:
static constexpr bool isReferenceCountingWaitFree();
bool ref();
+ void refRelaxed();
bool deref();
static constexpr bool isTestAndSetNative();
diff --git a/src/corelib/thread/qbasicatomic.h b/src/corelib/thread/qbasicatomic.h
index 43337648053..49e686a9de8 100644
--- a/src/corelib/thread/qbasicatomic.h
+++ b/src/corelib/thread/qbasicatomic.h
@@ -46,6 +46,7 @@ public:
static constexpr bool isReferenceCountingWaitFree() noexcept { return Ops::isReferenceCountingWaitFree(); }
bool ref() noexcept { return Ops::ref(_q_value); }
+ void refRelaxed() noexcept { Ops::fetchAndAddRelaxed(_q_value, 1); }
bool deref() noexcept { return Ops::deref(_q_value); }
static constexpr bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); }
diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h
index bb70678a958..6e4e532fd7d 100644
--- a/src/corelib/thread/qthread.h
+++ b/src/corelib/thread/qthread.h
@@ -172,27 +172,15 @@ inline Qt::HANDLE QThread::currentThreadId() noexcept
#elif defined(Q_PROCESSOR_X86_64) && ((defined(Q_OS_LINUX) && defined(__GLIBC__)) || defined(Q_OS_FREEBSD))
// x86_64 Linux, BSD uses FS
__asm__("mov %%fs:%c1, %0" : "=r" (tid) : "i" (2 * sizeof(void*)) : );
-#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN)
+#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN) && defined(Q_CC_MSVC)
// See https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
- // First get the pointer to the TIB
- quint8 *tib;
-# if defined(Q_CC_MINGW) // internal compiler error when using the intrinsics
- __asm__("movq %%gs:0x30, %0" : "=r" (tib) : :);
-# else
- tib = reinterpret_cast<quint8 *>(__readgsqword(0x30));
-# endif
- // Then read the thread ID
- tid = *reinterpret_cast<Qt::HANDLE *>(tib + 0x48);
-#elif defined(Q_PROCESSOR_X86_32) && defined(Q_OS_WIN)
- // First get the pointer to the TIB
- quint8 *tib;
-# if defined(Q_CC_MINGW) // internal compiler error when using the intrinsics
- __asm__("movl %%fs:0x18, %0" : "=r" (tib) : :);
-# else
- tib = reinterpret_cast<quint8 *>(__readfsdword(0x18));
-# endif
- // Then read the thread ID
- tid = *reinterpret_cast<Qt::HANDLE *>(tib + 0x24);
+ tid = reinterpret_cast<Qt::HANDLE>(__readgsqword(0x48));
+#elif defined(Q_PROCESSOR_X86_64) && defined(Q_OS_WIN) // !Q_CC_MSVC
+ __asm__("mov %%gs:0x48, %0" : "=r" (tid));
+#elif defined(Q_PROCESSOR_X86_32) && defined(Q_OS_WIN) && defined(Q_CC_MSVC)
+ tid = reinterpret_cast<Qt::HANDLE>(__readfsdword(0x24));
+#elif defined(Q_PROCESSOR_X86_32) && defined(Q_OS_WIN) // !Q_CC_MSVC
+ __asm__("mov %%fs:0x24, %0" : "=r" (tid));
#else
#undef QT_HAS_FAST_CURRENT_THREAD_ID
tid = currentThreadIdImpl();
diff --git a/src/corelib/time/qdatetime.cpp b/src/corelib/time/qdatetime.cpp
index 03eeed84465..974c486b915 100644
--- a/src/corelib/time/qdatetime.cpp
+++ b/src/corelib/time/qdatetime.cpp
@@ -517,6 +517,7 @@ QDate::QDate(int y, int m, int d, QCalendar cal)
*/
/*!
+ \overload primary
\fn bool QDate::isValid() const
Returns \c true if this date is valid; otherwise returns \c false.
@@ -525,6 +526,8 @@ QDate::QDate(int y, int m, int d, QCalendar cal)
*/
/*!
+ \overload primary
+
Returns the year of this date.
Uses \a cal as calendar, if supplied, else the Gregorian calendar.
@@ -557,8 +560,8 @@ int QDate::year(QCalendar cal) const
}
/*!
- \overload
- */
+ \overload year()
+*/
int QDate::year() const
{
@@ -571,6 +574,8 @@ int QDate::year() const
}
/*!
+ \overload primary
+
Returns the month-number for the date.
Numbers the months of the year starting with 1 for the first. Uses \a cal
@@ -609,8 +614,8 @@ int QDate::month(QCalendar cal) const
}
/*!
- \overload
- */
+ \overload month()
+*/
int QDate::month() const
{
@@ -623,6 +628,8 @@ int QDate::month() const
}
/*!
+ \overload primary
+
Returns the day of the month for this date.
Uses \a cal as calendar if supplied, else the Gregorian calendar (for which
@@ -642,8 +649,8 @@ int QDate::day(QCalendar cal) const
}
/*!
- \overload
- */
+ \overload day()
+*/
int QDate::day() const
{
@@ -656,6 +663,8 @@ int QDate::day() const
}
/*!
+ \overload primary
+
Returns the weekday (1 = Monday to 7 = Sunday) for this date.
Uses \a cal as calendar if supplied, else the Gregorian calendar. Returns 0
@@ -674,8 +683,8 @@ int QDate::dayOfWeek(QCalendar cal) const
}
/*!
- \overload
- */
+ \overload dayOfWeek()
+*/
int QDate::dayOfWeek() const
{
@@ -683,6 +692,8 @@ int QDate::dayOfWeek() const
}
/*!
+ \overload primary
+
Returns the day of the year (1 for the first day) for this date.
Uses \a cal as calendar if supplied, else the Gregorian calendar.
@@ -702,8 +713,8 @@ int QDate::dayOfYear(QCalendar cal) const
}
/*!
- \overload
- */
+ \overload dayOfYear()
+*/
int QDate::dayOfYear() const
{
@@ -715,6 +726,8 @@ int QDate::dayOfYear() const
}
/*!
+ \overload primary
+
Returns the number of days in the month for this date.
Uses \a cal as calendar if supplied, else the Gregorian calendar (for which
@@ -735,8 +748,8 @@ int QDate::daysInMonth(QCalendar cal) const
}
/*!
- \overload
- */
+ \overload daysInMonth()
+*/
int QDate::daysInMonth() const
{
@@ -749,6 +762,8 @@ int QDate::daysInMonth() const
}
/*!
+ \overload primary
+
Returns the number of days in the year for this date.
Uses \a cal as calendar if supplied, else the Gregorian calendar (for which
@@ -766,8 +781,8 @@ int QDate::daysInYear(QCalendar cal) const
}
/*!
- \overload
- */
+ \overload daysInYear()
+*/
int QDate::daysInYear() const
{
@@ -918,6 +933,7 @@ static QDateTime toEarliest(QDate day, const QTimeZone &zone)
/*!
\since 5.14
+ \overload primary
Returns the start-moment of the day.
@@ -972,8 +988,8 @@ QDateTime QDate::startOfDay(const QTimeZone &zone) const
}
/*!
- \overload
\since 6.5
+ \overload startOfDay()
*/
QDateTime QDate::startOfDay() const
{
@@ -982,8 +998,8 @@ QDateTime QDate::startOfDay() const
#if QT_DEPRECATED_SINCE(6, 9)
/*!
- \overload
\since 5.14
+ \overload startOfDay()
\deprecated [6.9] Use \c{startOfDay(const QTimeZone &)} instead.
Returns the start-moment of the day.
@@ -1073,6 +1089,7 @@ static QDateTime toLatest(QDate day, const QTimeZone &zone)
/*!
\since 5.14
+ \overload primary
Returns the end-moment of the day.
@@ -1127,8 +1144,8 @@ QDateTime QDate::endOfDay(const QTimeZone &zone) const
}
/*!
- \overload
\since 6.5
+ \overload endOfDay()
*/
QDateTime QDate::endOfDay() const
{
@@ -1137,8 +1154,8 @@ QDateTime QDate::endOfDay() const
#if QT_DEPRECATED_SINCE(6, 9)
/*!
- \overload
\since 5.14
+ \overload endOfDay()
\deprecated [6.9] Use \c{endOfDay(const QTimeZone &) instead.
Returns the end-moment of the day.
@@ -1199,7 +1216,7 @@ static QString toStringIsoDate(QDate date)
}
/*!
- \overload
+ \overload toString()
Returns the date as a string. The \a format parameter determines the format
of the string.
@@ -1245,9 +1262,10 @@ QString QDate::toString(Qt::DateFormat format) const
}
/*!
+ \since 5.14
+ \overload primary
\fn QString QDate::toString(const QString &format, QCalendar cal) const
\fn QString QDate::toString(QStringView format, QCalendar cal) const
- \since 5.14
Returns the date as a string. The \a format parameter determines the format
of the result string. If \a cal is supplied, it determines the calendar used
@@ -1313,8 +1331,8 @@ QString QDate::toString(QStringView format, QCalendar cal) const
// Out-of-line no-calendar overloads, since QCalendar is a non-trivial type
/*!
- \overload
\since 5.10
+ \overload toString()
*/
QString QDate::toString(QStringView format) const
{
@@ -1322,8 +1340,8 @@ QString QDate::toString(QStringView format) const
}
/*!
- \overload
\since 4.6
+ \overload toString()
*/
QString QDate::toString(const QString &format) const
{
@@ -1414,9 +1432,8 @@ QDate QDate::addDays(qint64 ndays) const
}
/*!
- \fn QDate QDate::addDuration(std::chrono::days ndays) const
-
\since 6.4
+ \fn QDate QDate::addDuration(std::chrono::days ndays) const
Returns a QDate object containing a date \a ndays later than the
date of this object (or earlier if \a ndays is negative).
@@ -1436,6 +1453,8 @@ QDate QDate::addDays(qint64 ndays) const
*/
/*!
+ \overload primary
+
Returns a QDate object containing a date \a nmonths later than the
date of this object (or earlier if \a nmonths is negative).
@@ -1477,7 +1496,7 @@ QDate QDate::addMonths(int nmonths, QCalendar cal) const
}
/*!
- \overload
+ \overload addMonths()
*/
QDate QDate::addMonths(int nmonths) const
@@ -1509,6 +1528,8 @@ QDate QDate::addMonths(int nmonths) const
}
/*!
+ \overload primary
+
Returns a QDate object containing a date \a nyears later than the
date of this object (or earlier if \a nyears is negative).
@@ -1542,7 +1563,7 @@ QDate QDate::addYears(int nyears, QCalendar cal) const
}
/*!
- \overload
+ \overload addYears()
*/
QDate QDate::addYears(int nyears) const
@@ -1638,6 +1659,7 @@ qint64 QDate::daysTo(QDate d) const
#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
+ \overload
\fn QDate QDate::fromString(const QString &string, Qt::DateFormat format)
Returns the QDate represented by the \a string, using the
@@ -1651,8 +1673,8 @@ qint64 QDate::daysTo(QDate d) const
*/
/*!
- \overload
\since 6.0
+ \overload fromString()
*/
QDate QDate::fromString(QStringView string, Qt::DateFormat format)
{
@@ -1702,6 +1724,7 @@ QDate QDate::fromString(QStringView string, Qt::DateFormat format)
}
/*!
+ \overload primary
\fn QDate QDate::fromString(const QString &string, const QString &format, int baseYear, QCalendar cal)
Returns the QDate represented by the \a string, using the \a
@@ -1833,14 +1856,14 @@ QDate QDate::fromString(QStringView string, Qt::DateFormat format)
*/
/*!
- \fn QDate QDate::fromString(QStringView string, QStringView format, QCalendar cal)
- \overload
\since 6.0
+ \overload fromString()
+ \fn QDate QDate::fromString(QStringView string, QStringView format, QCalendar cal)
*/
/*!
- \overload
\since 6.0
+ \overload fromString()
*/
QDate QDate::fromString(const QString &string, QStringView format, int baseYear, QCalendar cal)
{
@@ -1860,34 +1883,34 @@ QDate QDate::fromString(const QString &string, QStringView format, int baseYear,
}
/*!
- \fn QDate QDate::fromString(const QString &string, const QString &format, QCalendar cal)
- \overload
\since 5.14
+ \overload fromString()
+ \fn QDate QDate::fromString(const QString &string, const QString &format, QCalendar cal)
*/
/*!
- \fn QDate QDate::fromString(const QString &string, QStringView format, QCalendar cal)
- \overload
\since 6.0
+ \overload fromString()
+ \fn QDate QDate::fromString(const QString &string, QStringView format, QCalendar cal)
*/
/*!
- \fn QDate QDate::fromString(QStringView string, QStringView format, int baseYear, QCalendar cal)
- \overload
\since 6.7
+ \overload fromString()
+ \fn QDate QDate::fromString(QStringView string, QStringView format, int baseYear, QCalendar cal)
*/
/*!
- \fn QDate QDate::fromString(QStringView string, QStringView format, int baseYear)
- \overload
\since 6.7
+ \overload fromString()
+ \fn QDate QDate::fromString(QStringView string, QStringView format, int baseYear)
Uses a default-constructed QCalendar.
*/
/*!
- \overload
\since 6.7
+ \overload fromString()
Uses a default-constructed QCalendar.
*/
@@ -1897,16 +1920,16 @@ QDate QDate::fromString(const QString &string, QStringView format, int baseYear)
}
/*!
- \fn QDate QDate::fromString(const QString &string, const QString &format, int baseYear)
- \overload
\since 6.7
+ \overload fromString()
+ \fn QDate QDate::fromString(const QString &string, const QString &format, int baseYear)
Uses a default-constructed QCalendar.
*/
#endif // datestring
/*!
- \overload
+ \overload isValid()
Returns \c true if the specified date (\a year, \a month, and \a day) is
valid in the Gregorian calendar; otherwise returns \c false.
@@ -2037,6 +2060,8 @@ QTime::QTime(int h, int m, int s, int ms)
*/
/*!
+ \overload primary
+
Returns \c true if the time is valid; otherwise returns \c false. For example,
the time 23:30:55.746 is valid, but 24:12:30 is invalid.
@@ -2115,7 +2140,7 @@ int QTime::msec() const
#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
- \overload
+ \overload toString()
Returns the time as a string. The \a format parameter determines
the format of the string.
@@ -2155,6 +2180,7 @@ QString QTime::toString(Qt::DateFormat format) const
}
/*!
+ \overload primary
\fn QString QTime::toString(const QString &format) const
\fn QString QTime::toString(QStringView format) const
@@ -2261,11 +2287,11 @@ QString QTime::toString(Qt::DateFormat format) const
\sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString()
*/
-// ### Qt 7 The 't' format specifiers should be specific to QDateTime (compare fromString).
QString QTime::toString(QStringView format) const
{
return QLocale::c().toString(*this, format);
}
+// ### Qt 7 The 't' format specifiers should be specific to QDateTime (compare fromString).
#endif // datestring
/*!
@@ -2557,6 +2583,7 @@ static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool *
}
/*!
+ \overload
\fn QTime QTime::fromString(const QString &string, Qt::DateFormat format)
Returns the time represented in the \a string as a QTime using the
@@ -2566,8 +2593,8 @@ static QTime fromIsoTimeString(QStringView string, Qt::DateFormat format, bool *
*/
/*!
- \overload
\since 6.0
+ \overload fromString()
*/
QTime QTime::fromString(QStringView string, Qt::DateFormat format)
{
@@ -2586,6 +2613,7 @@ QTime QTime::fromString(QStringView string, Qt::DateFormat format)
}
/*!
+ \overload primary
\fn QTime QTime::fromString(const QString &string, const QString &format)
Returns the QTime represented by the \a string, using the \a
@@ -2664,14 +2692,14 @@ QTime QTime::fromString(QStringView string, Qt::DateFormat format)
*/
/*!
- \fn QTime QTime::fromString(QStringView string, QStringView format)
- \overload
\since 6.0
+ \overload fromString()
+ \fn QTime QTime::fromString(QStringView string, QStringView format)
*/
/*!
- \overload
\since 6.0
+ \overload fromString()
*/
QTime QTime::fromString(const QString &string, QStringView format)
{
@@ -2691,7 +2719,7 @@ QTime QTime::fromString(const QString &string, QStringView format)
/*!
- \overload
+ \overload isValid()
Returns \c true if the specified time is valid; otherwise returns
false.
@@ -4012,6 +4040,7 @@ QDateTime::QDateTime(QDate date, QTime time, Qt::TimeSpec spec, int offsetSecond
/*!
\since 5.2
+ \overload primary
Constructs a datetime with the given \a date and \a time, using the time
representation described by \a timeZone.
@@ -4620,7 +4649,7 @@ void QDateTime::setSecsSinceEpoch(qint64 secs)
#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
- \overload
+ \overload toString()
Returns the datetime as a string in the \a format given.
@@ -4712,9 +4741,10 @@ QString QDateTime::toString(Qt::DateFormat format) const
}
/*!
+ \since 5.14
+ \overload primary
\fn QString QDateTime::toString(const QString &format, QCalendar cal) const
\fn QString QDateTime::toString(QStringView format, QCalendar cal) const
- \since 5.14
Returns the datetime as a string. The \a format parameter determines the
format of the result string. If \a cal is supplied, it determines the
@@ -4761,8 +4791,8 @@ QString QDateTime::toString(QStringView format, QCalendar cal) const
// Out-of-line no-calendar overloads, since QCalendar is a non-trivial type
/*!
- \overload
\since 5.10
+ \overload toString()
*/
QString QDateTime::toString(QStringView format) const
{
@@ -4770,8 +4800,8 @@ QString QDateTime::toString(QStringView format) const
}
/*!
- \overload
\since 4.6
+ \overload toString()
*/
QString QDateTime::toString(const QString &format) const
{
@@ -5370,6 +5400,7 @@ Qt::weak_ordering compareThreeWay(const QDateTime &lhs, const QDateTime &rhs)
/*!
\since 6.5
+ \overload primary
\fn QDateTime QDateTime::currentDateTime(const QTimeZone &zone)
Returns the system clock's current datetime, using the time representation
@@ -5379,8 +5410,8 @@ Qt::weak_ordering compareThreeWay(const QDateTime &lhs, const QDateTime &rhs)
*/
/*!
- \overload
\since 0.90
+ \overload currentDateTime()
*/
QDateTime QDateTime::currentDateTime()
{
@@ -5426,8 +5457,9 @@ QDateTime QDateTime::currentDateTimeUtc()
*/
/*!
- \fn template <typename Clock, typename Duration> QDateTime QDateTime::fromStdTimePoint(const std::chrono::time_point<Clock, Duration> &time)
\since 6.4
+ \overload primary
+ \fn template <typename Clock, typename Duration> QDateTime QDateTime::fromStdTimePoint(const std::chrono::time_point<Clock, Duration> &time)
Constructs a datetime representing the same point in time as \a time,
using Qt::UTC as its time representation.
@@ -5451,7 +5483,7 @@ QDateTime QDateTime::currentDateTimeUtc()
/*!
\since 6.4
- \overload
+ \overload fromStdTimePoint()
Constructs a datetime representing the same point in time as \a time,
using Qt::UTC as its time representation.
@@ -5627,7 +5659,7 @@ qint64 QDateTime::currentSecsSinceEpoch() noexcept
#if QT_DEPRECATED_SINCE(6, 9)
/*!
\since 5.2
- \overload
+ \overload fromMSecsSinceEpoch()
\deprecated [6.9] Pass a \l QTimeZone instead, or omit \a spec and \a offsetSeconds.
Returns a datetime representing a moment the given number \a msecs of
@@ -5656,7 +5688,7 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, Qt::TimeSpec spec, int of
/*!
\since 5.8
- \overload
+ \overload fromSecsSinceEpoch
\deprecated [6.9] Pass a \l QTimeZone instead, or omit \a spec and \a offsetSeconds.
Returns a datetime representing a moment the given number \a secs of seconds
@@ -5686,6 +5718,7 @@ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, Qt::TimeSpec spec, int offs
/*!
\since 5.2
+ \overload primary
Returns a datetime representing a moment the given number \a msecs of
milliseconds after the start, in UTC, of the year 1970, described as
@@ -5707,7 +5740,7 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs, const QTimeZone &timeZone
}
/*!
- \overload
+ \overload fromMSecsSinceEpoch()
*/
QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
{
@@ -5716,6 +5749,7 @@ QDateTime QDateTime::fromMSecsSinceEpoch(qint64 msecs)
/*!
\since 5.8
+ \overload primary
Returns a datetime representing a moment the given number \a secs of seconds
after the start, in UTC, of the year 1970, described as specified by \a
@@ -5737,7 +5771,7 @@ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs, const QTimeZone &timeZone)
}
/*!
- \overload
+ \overload fromSecsSinceEpoch()
*/
QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs)
{
@@ -5747,6 +5781,7 @@ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs)
#if QT_CONFIG(datestring) // depends on, so implies, textdate
/*!
+ \overload
\fn QDateTime QDateTime::fromString(const QString &string, Qt::DateFormat format)
Returns the QDateTime represented by the \a string, using the
@@ -5759,8 +5794,8 @@ QDateTime QDateTime::fromSecsSinceEpoch(qint64 secs)
*/
/*!
- \overload
\since 6.0
+ \overload fromString()
*/
QDateTime QDateTime::fromString(QStringView string, Qt::DateFormat format)
{
@@ -5901,6 +5936,7 @@ QDateTime QDateTime::fromString(QStringView string, Qt::DateFormat format)
}
/*!
+ \overload primary
\fn QDateTime QDateTime::fromString(const QString &string, const QString &format, int baseYear, QCalendar cal)
Returns the QDateTime represented by the \a string, using the \a
@@ -5984,14 +6020,14 @@ QDateTime QDateTime::fromString(QStringView string, Qt::DateFormat format)
*/
/*!
- \fn QDateTime QDateTime::fromString(QStringView string, QStringView format, QCalendar cal)
- \overload
\since 6.0
+ \overload fromString()
+ \fn QDateTime QDateTime::fromString(QStringView string, QStringView format, QCalendar cal)
*/
/*!
- \overload
\since 6.0
+ \overload fromString()
*/
QDateTime QDateTime::fromString(const QString &string, QStringView format, int baseYear,
QCalendar cal)
@@ -6015,34 +6051,34 @@ QDateTime QDateTime::fromString(const QString &string, QStringView format, int b
}
/*!
- \fn QDateTime QDateTime::fromString(const QString &string, const QString &format, QCalendar cal)
- \overload
\since 5.14
+ \overload fromString()
+ \fn QDateTime QDateTime::fromString(const QString &string, const QString &format, QCalendar cal)
*/
/*!
- \fn QDateTime QDateTime::fromString(const QString &string, QStringView format, QCalendar cal)
- \overload
\since 6.0
+ \overload fromString()
+ \fn QDateTime QDateTime::fromString(const QString &string, QStringView format, QCalendar cal)
*/
/*!
- \fn QDateTime QDateTime::fromString(QStringView string, QStringView format, int baseYear, QCalendar cal)
- \overload
\since 6.7
+ \overload fromString()
+ \fn QDateTime QDateTime::fromString(QStringView string, QStringView format, int baseYear, QCalendar cal)
*/
/*!
- \fn QDateTime QDateTime::fromString(QStringView string, QStringView format, int baseYear)
- \overload
\since 6.7
+ \overload fromString()
+ \fn QDateTime QDateTime::fromString(QStringView string, QStringView format, int baseYear)
Uses a default-constructed QCalendar.
*/
/*!
- \overload
\since 6.7
+ \overload fromString()
Uses a default-constructed QCalendar.
*/
@@ -6052,9 +6088,9 @@ QDateTime QDateTime::fromString(const QString &string, QStringView format, int b
}
/*!
- \fn QDateTime QDateTime::fromString(const QString &string, const QString &format, int baseYear)
- \overload
\since 6.7
+ \overload fromString()
+ \fn QDateTime QDateTime::fromString(const QString &string, const QString &format, int baseYear)
Uses a default-constructed QCalendar.
*/
diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp
index d49ac42301e..10882738a39 100644
--- a/src/corelib/time/qdatetimeparser.cpp
+++ b/src/corelib/time/qdatetimeparser.cpp
@@ -1245,7 +1245,7 @@ static auto findZoneByLongName(QStringView str, const QLocale &locale, const QDa
// (We don't want offset format to match 'tttt', so do need to limit this.)
// The final fall-back for QTZL's localeName() is a zoneOffsetFormat(,,NarrowFormat,,):
if (!pfx)
- pfx = QTimeZonePrivate::findNarrowOffsetPrefix(str, locale, QLocale::NarrowFormat);
+ pfx = QTimeZonePrivate::findNarrowOffsetPrefix(str, locale);
if (!pfx)
pfx = QTimeZonePrivate::findLongUtcPrefix(str);
if (pfx) {
diff --git a/src/corelib/time/qgregoriancalendar.cpp b/src/corelib/time/qgregoriancalendar.cpp
index d46d24ac30d..dfb99c5073d 100644
--- a/src/corelib/time/qgregoriancalendar.cpp
+++ b/src/corelib/time/qgregoriancalendar.cpp
@@ -31,6 +31,7 @@ static_assert(qDivMod<86400>(-172800).remainder == 0);
/*!
\since 5.14
+ \internal
\class QGregorianCalendar
\inmodule QtCore
diff --git a/src/corelib/time/qjalalicalendar.cpp b/src/corelib/time/qjalalicalendar.cpp
index 8bc9fe125e7..683ce6e7712 100644
--- a/src/corelib/time/qjalalicalendar.cpp
+++ b/src/corelib/time/qjalalicalendar.cpp
@@ -39,6 +39,7 @@ qint64 firstDayOfYear(int year, int cycleNo)
/*!
\since 5.14
+ \internal
\class QJalaliCalendar
\inmodule QtCore
diff --git a/src/corelib/time/qjuliancalendar.cpp b/src/corelib/time/qjuliancalendar.cpp
index 47da952b84a..cf3718f471d 100644
--- a/src/corelib/time/qjuliancalendar.cpp
+++ b/src/corelib/time/qjuliancalendar.cpp
@@ -13,6 +13,7 @@ using namespace QRoundingDown;
/*!
\since 5.14
+ \internal
\class QJulianCalendar
\inmodule QtCore
diff --git a/src/corelib/time/qmilankoviccalendar.cpp b/src/corelib/time/qmilankoviccalendar.cpp
index a3ffa2a3053..14aef83afe3 100644
--- a/src/corelib/time/qmilankoviccalendar.cpp
+++ b/src/corelib/time/qmilankoviccalendar.cpp
@@ -13,6 +13,7 @@ using namespace QRoundingDown;
/*!
\since 5.14
+ \internal
\class QMilankovicCalendar
\inmodule QtCore
diff --git a/src/corelib/time/qromancalendar.cpp b/src/corelib/time/qromancalendar.cpp
index ae113cf8323..a8ce027275a 100644
--- a/src/corelib/time/qromancalendar.cpp
+++ b/src/corelib/time/qromancalendar.cpp
@@ -9,6 +9,7 @@ QT_BEGIN_NAMESPACE
/*!
\since 5.14
+ \internal
\class QRomanCalendar
\inmodule QtCore
diff --git a/src/corelib/time/qtimezone.cpp b/src/corelib/time/qtimezone.cpp
index f44c681ea80..7b43aab22d1 100644
--- a/src/corelib/time/qtimezone.cpp
+++ b/src/corelib/time/qtimezone.cpp
@@ -29,7 +29,7 @@ static QTimeZonePrivate *newBackendTimeZone()
return new QMacTimeZonePrivate();
#elif defined(Q_OS_ANDROID)
return new QAndroidTimeZonePrivate();
-#elif defined(Q_OS_UNIX)
+#elif defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
return new QTzTimeZonePrivate();
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate();
@@ -50,7 +50,7 @@ static QTimeZonePrivate *newBackendTimeZone(const QByteArray &ianaId)
return new QMacTimeZonePrivate(ianaId);
#elif defined(Q_OS_ANDROID)
return new QAndroidTimeZonePrivate(ianaId);
-#elif defined(Q_OS_UNIX)
+#elif defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
return new QTzTimeZonePrivate(ianaId);
#elif QT_CONFIG(icu)
return new QIcuTimeZonePrivate(ianaId);
@@ -1482,7 +1482,8 @@ QTimeZone QTimeZone::utc()
bool QTimeZone::isTimeZoneIdAvailable(const QByteArray &ianaId)
{
-#if defined(Q_OS_UNIX) && !(defined(Q_OS_ANDROID) || defined(Q_OS_DARWIN))
+#if defined(Q_OS_UNIX) && !(QT_CONFIG(timezone_tzdb) || defined(Q_OS_DARWIN) \
+ || defined(Q_OS_ANDROID) || defined(Q_OS_VXWORKS))
// Keep #if-ery consistent with selection of QTzTimeZonePrivate in
// newBackendTimeZone(). Skip the pre-check, as the TZ backend accepts POSIX
// zone IDs, which need not be valid IANA IDs. See also QTBUG-112006.
diff --git a/src/corelib/time/qtimezonelocale.cpp b/src/corelib/time/qtimezonelocale.cpp
index a83b4da8b1b..a794682fe0b 100644
--- a/src/corelib/time/qtimezonelocale.cpp
+++ b/src/corelib/time/qtimezonelocale.cpp
@@ -980,10 +980,10 @@ QTimeZonePrivate::findLongNamePrefix(QStringView text, const QLocale &locale,
}
QTimeZonePrivate::NamePrefixMatch
-QTimeZonePrivate::findNarrowOffsetPrefix(QStringView text, const QLocale &locale,
- QLocale::FormatType scale)
+QTimeZonePrivate::findNarrowOffsetPrefix(QStringView text, const QLocale &locale)
{
- if (auto match = matchOffsetFormat(text, locale, locale.d->m_index, scale)) {
+ // NB: uses QLocale::FormatType with non-canonical meaning !
+ if (auto match = matchOffsetFormat(text, locale, locale.d->m_index, QLocale::NarrowFormat)) {
// Check offset is sane:
if (QTimeZone::MinUtcOffsetSecs <= match.offset
&& match.offset <= QTimeZone::MaxUtcOffsetSecs) {
diff --git a/src/corelib/time/qtimezoneprivate.cpp b/src/corelib/time/qtimezoneprivate.cpp
index d8434f4fe1b..556f7e21402 100644
--- a/src/corelib/time/qtimezoneprivate.cpp
+++ b/src/corelib/time/qtimezoneprivate.cpp
@@ -955,7 +955,7 @@ QTimeZonePrivate::findLongNamePrefix(QStringView text, const QLocale &locale,
}
QTimeZonePrivate::NamePrefixMatch
-QTimeZonePrivate::findNarrowOffsetPrefix(QStringView, const QLocale &, QLocale::FormatType)
+QTimeZonePrivate::findNarrowOffsetPrefix(QStringView, const QLocale &)
{
// Seemingly only needed in the timezonelocale case.
return {};
diff --git a/src/corelib/time/qtimezoneprivate_p.h b/src/corelib/time/qtimezoneprivate_p.h
index b1217402ce7..0f19d1fd025 100644
--- a/src/corelib/time/qtimezoneprivate_p.h
+++ b/src/corelib/time/qtimezoneprivate_p.h
@@ -166,8 +166,7 @@ public:
};
static NamePrefixMatch findLongNamePrefix(QStringView text, const QLocale &locale,
std::optional<qint64> atEpochMillis = std::nullopt);
- static NamePrefixMatch findNarrowOffsetPrefix(QStringView text, const QLocale &locale,
- QLocale::FormatType scale);
+ static NamePrefixMatch findNarrowOffsetPrefix(QStringView text, const QLocale &locale);
// Match the unlocalized long form of QUtcTimeZonePrivate:
static NamePrefixMatch findLongUtcPrefix(QStringView text);
@@ -389,7 +388,7 @@ private:
QJniObject androidTimeZone;
};
-#elif defined(Q_OS_UNIX)
+#elif defined(Q_OS_UNIX) && !defined(Q_OS_VXWORKS)
struct QTzTransitionTime
{
qint64 atMSecsSinceEpoch;
diff --git a/src/corelib/tools/qarraydata.h b/src/corelib/tools/qarraydata.h
index 5aadbeda538..aadf33ed5ae 100644
--- a/src/corelib/tools/qarraydata.h
+++ b/src/corelib/tools/qarraydata.h
@@ -58,7 +58,7 @@ struct QArrayData
/// Returns true if sharing took place
bool ref() noexcept
{
- ref_.ref();
+ ref_.refRelaxed(); // suffices for ref-counting
return true;
}
diff --git a/src/corelib/tools/qiterator.qdoc b/src/corelib/tools/qiterator.qdoc
index 3d8ea595167..d517457027a 100644
--- a/src/corelib/tools/qiterator.qdoc
+++ b/src/corelib/tools/qiterator.qdoc
@@ -165,7 +165,7 @@
position between the second and third item, and returns the second
item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
Here's how to iterate over the elements in reverse order:
@@ -211,7 +211,7 @@
position between the second and third item, returning the second
item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
If you want to find all occurrences of a particular value, use
findNext() in a loop.
@@ -260,7 +260,7 @@
position between the second and third item, returning the second
item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
Here's how to iterate over the elements in reverse order:
@@ -321,7 +321,7 @@
position between the second and third item, returning the second
item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
If you want to remove items as you iterate over the set, use
remove().
@@ -718,7 +718,7 @@
next() advances the iterator to the position between the second
and third item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
Here's how to iterate over the elements in reverse order:
@@ -768,7 +768,7 @@
next() advances the iterator to the position between the second
and third item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
Here's how to iterate over the elements in reverse order:
@@ -819,7 +819,7 @@
next() advances the iterator to the position between the second
and third item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
If you want to find all occurrences of a particular value, use
findNext() in a loop. For example:
@@ -867,7 +867,7 @@
next() advances the iterator to the position between the second
and third item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
Here's how to iterate over the elements in reverse order:
@@ -931,7 +931,7 @@
next() advances the iterator to the position between the second
and third item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
Here's how to iterate over the elements in reverse order:
@@ -994,7 +994,7 @@
next() advances the iterator to the position between the second
and third item; and so on.
- \image javaiterators1.png
+ \image javaiterators1.svg Java-style iterators point between items
If you want to find all occurrences of a particular value, use
findNext() in a loop. For example:
diff --git a/src/dbus/qt_attribution.json b/src/dbus/qt_attribution.json
index 9e00c2a8bd9..067e3013bb1 100644
--- a/src/dbus/qt_attribution.json
+++ b/src/dbus/qt_attribution.json
@@ -1,6 +1,6 @@
{
"Id": "libdbus-1-headers",
- "Name": "libdus-1 headers",
+ "Name": "libdbus-1 headers",
"QDocModule": "qtdbus",
"QtUsage": "Qt D-Bus uses constants and typedefs from libdbus-1 headers.",
diff --git a/src/gui/accessible/linux/atspiadaptor.cpp b/src/gui/accessible/linux/atspiadaptor.cpp
index e91539d6ee3..dad0ac2b74a 100644
--- a/src/gui/accessible/linux/atspiadaptor.cpp
+++ b/src/gui/accessible/linux/atspiadaptor.cpp
@@ -1688,6 +1688,17 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
sendReply(connection, message, QVariant::fromValue(QDBusVariant(interface->text(QAccessible::Help))));
} else if (function == "GetState"_L1) {
quint64 spiState = spiStatesFromQState(interface->state());
+ if (QAccessibleAttributesInterface *attributesIface = interface->attributesInterface()) {
+ const QVariant orientationVariant =
+ attributesIface->attributeValue(QAccessible::Attribute::Orientation);
+ if (orientationVariant.isValid()) {
+ Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>());
+ const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>();
+ setSpiStateBit(&spiState,
+ orientation == Qt::Horizontal ? ATSPI_STATE_HORIZONTAL
+ : ATSPI_STATE_VERTICAL);
+ }
+ }
if (interface->tableInterface()) {
// For tables, setting manages_descendants should
// indicate to the client that it cannot cache these
@@ -1877,7 +1888,7 @@ void AtSpiAdaptor::addMatchingDescendants(QList<QAccessibleInterface *> &matches
const QSpiMatchRuleMatcher &matcher, bool invert,
int count, bool traverse)
{
- if (!accessible || matches.size() >= count)
+ if (!accessible || (count != 0 && matches.size() >= count))
return;
const int childCount = accessible->childCount();
@@ -1889,7 +1900,7 @@ void AtSpiAdaptor::addMatchingDescendants(QList<QAccessibleInterface *> &matches
if (traverse)
addMatchingDescendants(matches, child, matcher, invert, count, traverse);
- if (matches.size() >= count)
+ if (count != 0 && matches.size() >= count)
return;
}
}
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index eeb06c535b8..30ebe90da0b 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -458,6 +458,9 @@ Q_STATIC_LOGGING_CATEGORY(lcAccessibilityCore, "qt.accessibility.core");
differs from the application's default locale, e.g. for documents
or paragraphs within a document that use a language that differs
from the application's user interface language.
+ \value [since 6.11] Orientation value type: \a Qt::Orientation
+ Orientation of the element. This attribute conceptually matches
+ the "aria-orientation" property in ARIA.
\sa QAccessibleAttributesInterface
*/
@@ -968,9 +971,21 @@ void QAccessible::updateAccessibility(QAccessibleEvent *event)
pfAccessibility->notifyAccessibilityUpdate(event);
}
+static std::pair<int, int> qAccessibleTextBoundaryHelperHelper(QTextCursor &cursor,
+ QTextCursor::MoveOperation start,
+ QTextCursor::MoveOperation end)
+{
+ std::pair<int, int> result;
+ cursor.movePosition(start, QTextCursor::MoveAnchor);
+ result.first = cursor.position();
+ cursor.movePosition(end, QTextCursor::KeepAnchor);
+ result.second = cursor.position();
+ return result;
+}
+
/*!
\internal
- \brief getBoundaries is a helper function to find the accessible text boundaries for QTextCursor based documents.
+ \brief qAccessibleTextBoundaryHelper is a helper function to find the accessible text boundaries for QTextCursor based documents.
\param documentCursor a valid cursor bound to the document (not null). It needs to ba at the position to look for the boundary
\param boundaryType the type of boundary to find
\return the boundaries as pair
@@ -979,32 +994,20 @@ std::pair< int, int > QAccessible::qAccessibleTextBoundaryHelper(const QTextCurs
{
Q_ASSERT(!offsetCursor.isNull());
- QTextCursor endCursor = offsetCursor;
- endCursor.movePosition(QTextCursor::End);
- int characterCount = endCursor.position();
-
- std::pair<int, int> result;
QTextCursor cursor = offsetCursor;
switch (boundaryType) {
case CharBoundary:
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
+ return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::NoMove,
+ QTextCursor::NextCharacter);
case WordBoundary:
- cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
+ return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::StartOfWord,
+ QTextCursor::EndOfWord);
case SentenceBoundary: {
// QCursor does not provide functionality to move to next sentence.
// We therefore find the current block, then go through the block using
// QTextBoundaryFinder and find the sentence the \offset represents
- cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- result.second = cursor.position();
+ std::pair<int, int> result = qAccessibleTextBoundaryHelperHelper(
+ cursor, QTextCursor::StartOfBlock, QTextCursor::EndOfBlock);
QString blockText = cursor.selectedText();
const int offsetWithinBlockText = offsetCursor.position() - result.first;
QTextBoundaryFinder sentenceFinder(QTextBoundaryFinder::Sentence, blockText);
@@ -1018,25 +1021,19 @@ std::pair< int, int > QAccessible::qAccessibleTextBoundaryHelper(const QTextCurs
result.second = result.first + nextBoundary;
if (prevBoundary != -1)
result.first += prevBoundary;
- break; }
+ return result;
+ }
case LineBoundary:
- cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
+ return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::StartOfLine,
+ QTextCursor::EndOfLine);
case ParagraphBoundary:
- cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
- result.first = cursor.position();
- cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
- result.second = cursor.position();
- break;
+ return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::StartOfBlock,
+ QTextCursor::EndOfBlock);
case NoBoundary:
- result.first = 0;
- result.second = characterCount;
- break;
+ return qAccessibleTextBoundaryHelperHelper(cursor, QTextCursor::Start, QTextCursor::End);
}
- return result;
+
+ Q_UNREACHABLE_RETURN({});
}
/*!
@@ -2274,13 +2271,16 @@ QString QAccessibleTextInterface::textBeforeOffset(int offset, QAccessible::Text
break;
} while (boundary.toPreviousBoundary() > 0);
Q_ASSERT(boundary.position() >= 0);
- *endOffset = boundary.position();
+ const int endPos = boundary.position();
while (boundary.toPreviousBoundary() > 0) {
if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
break;
}
- Q_ASSERT(boundary.position() >= 0);
+ if (boundary.position() < 0)
+ return QString();
+
+ *endOffset = endPos;
*startOffset = boundary.position();
return txt.mid(*startOffset, *endOffset - *startOffset);
@@ -2437,13 +2437,17 @@ QString QAccessibleTextInterface::textAtOffset(int offset, QAccessible::TextBoun
break;
} while (boundary.toPreviousBoundary() > 0);
Q_ASSERT(boundary.position() >= 0);
- *startOffset = boundary.position();
+ const int startPos = boundary.position();
while (boundary.toNextBoundary() < txt.size()) {
if ((boundary.boundaryReasons() & (QTextBoundaryFinder::StartOfItem | QTextBoundaryFinder::EndOfItem)))
break;
+ if (boundary.position() == -1)
+ return QString();
}
+
Q_ASSERT(boundary.position() <= txt.size());
+ *startOffset = startPos;
*endOffset = boundary.position();
return txt.mid(*startOffset, *endOffset - *startOffset);
diff --git a/src/gui/accessible/qaccessible_base.h b/src/gui/accessible/qaccessible_base.h
index 31b97880ffc..3881c6346a0 100644
--- a/src/gui/accessible/qaccessible_base.h
+++ b/src/gui/accessible/qaccessible_base.h
@@ -156,8 +156,6 @@ public:
quint64 searchEdit : 1;
- // quint64 horizontal : 1;
- // quint64 vertical : 1;
// quint64 invalidEntry : 1;
// quint64 managesDescendants : 1;
// quint64 singleLine : 1; // we have multi line, this is redundant.
@@ -380,6 +378,7 @@ public:
Custom,
Level,
Locale,
+ Orientation,
};
Q_ENUM(Attribute)
diff --git a/src/gui/accessible/qaccessiblehelper.cpp b/src/gui/accessible/qaccessiblehelper.cpp
index 2ae8ebbac08..9ea72b1f6c9 100644
--- a/src/gui/accessible/qaccessiblehelper.cpp
+++ b/src/gui/accessible/qaccessiblehelper.cpp
@@ -3,6 +3,8 @@
#include "qaccessiblehelper_p.h"
+#include <QtGui/qtextcursor.h>
+
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
@@ -48,4 +50,79 @@ QString qt_accStripAmp(const QString &text)
return newText.replace("&&"_L1, "&"_L1);
}
+QString qt_accTextBeforeOffsetHelper(const QAccessibleTextInterface &textInterface,
+ const QTextCursor &textCursor, int offset,
+ QAccessible::TextBoundaryType boundaryType, int *startOffset,
+ int *endOffset)
+{
+ Q_ASSERT(startOffset);
+ Q_ASSERT(endOffset);
+ *startOffset = *endOffset = -1;
+
+ QTextCursor cursor = textCursor;
+ cursor.setPosition(offset);
+ std::pair<int, int> boundaries =
+ QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ if (boundaries.second > offset) {
+ cursor.setPosition(boundaries.first);
+ while (boundaries.second > offset) {
+ if (!cursor.movePosition(QTextCursor::PreviousCharacter))
+ return QString();
+ boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ }
+ }
+
+ *startOffset = boundaries.first;
+ *endOffset = boundaries.second;
+
+ return textInterface.text(boundaries.first, boundaries.second);
+}
+
+QString qt_accTextAfterOffsetHelper(const QAccessibleTextInterface &textInterface,
+ const QTextCursor &textCursor, int offset,
+ QAccessible::TextBoundaryType boundaryType, int *startOffset,
+ int *endOffset)
+{
+ Q_ASSERT(startOffset);
+ Q_ASSERT(endOffset);
+ *startOffset = *endOffset = -1;
+
+ QTextCursor cursor = textCursor;
+ cursor.setPosition(offset);
+ std::pair<int, int> boundaries =
+ QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ if (boundaries.first <= offset) {
+ cursor.setPosition(boundaries.second);
+ while (boundaries.first <= offset) {
+ if (!cursor.movePosition(QTextCursor::NextCharacter))
+ return QString();
+ boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+ }
+ }
+
+ *startOffset = boundaries.first;
+ *endOffset = boundaries.second;
+
+ return textInterface.text(boundaries.first, boundaries.second);
+}
+
+QString qt_accTextAtOffsetHelper(const QAccessibleTextInterface &textInterface,
+ const QTextCursor &textCursor, int offset,
+ QAccessible::TextBoundaryType boundaryType, int *startOffset,
+ int *endOffset)
+{
+ Q_ASSERT(startOffset);
+ Q_ASSERT(endOffset);
+
+ QTextCursor cursor = textCursor;
+ cursor.setPosition(offset);
+ std::pair<int, int> boundaries =
+ QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
+
+ *startOffset = boundaries.first;
+ *endOffset = boundaries.second;
+
+ return textInterface.text(boundaries.first, boundaries.second);
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/accessible/qaccessiblehelper_p.h b/src/gui/accessible/qaccessiblehelper_p.h
index 38cc493fdea..03cccbbe539 100644
--- a/src/gui/accessible/qaccessiblehelper_p.h
+++ b/src/gui/accessible/qaccessiblehelper_p.h
@@ -16,12 +16,30 @@
//
#include <QtCore/QString>
+#include <QtGui/qaccessible.h>
#include <QtGui/qtguiglobal.h>
+class QTextCursor;
+
QT_BEGIN_NAMESPACE
Q_GUI_EXPORT QString qt_accStripAmp(const QString &text);
+Q_GUI_EXPORT QString qt_accTextBeforeOffsetHelper(const QAccessibleTextInterface &textInterface,
+ const QTextCursor &textCursor, int offset,
+ QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+
+Q_GUI_EXPORT QString qt_accTextAfterOffsetHelper(const QAccessibleTextInterface &textInterface,
+ const QTextCursor &textCursor, int offset,
+ QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+
+Q_GUI_EXPORT QString qt_accTextAtOffsetHelper(const QAccessibleTextInterface &textInterface,
+ const QTextCursor &textCursor, int offset,
+ QAccessible::TextBoundaryType boundaryType,
+ int *startOffset, int *endOffset);
+
QT_END_NAMESPACE
#endif // QACCESSIBLEHELPER_P_H
diff --git a/src/gui/configure.cmake b/src/gui/configure.cmake
index ad76bb095a0..5001f2deeec 100644
--- a/src/gui/configure.cmake
+++ b/src/gui/configure.cmake
@@ -1217,17 +1217,6 @@ qt_feature("xcb-egl-plugin" PRIVATE
CONDITION QT_FEATURE_egl AND QT_FEATURE_opengl
EMIT_IF QT_FEATURE_xcb
)
-qt_feature("xcb-native-painting" PRIVATE
- LABEL "Native painting (experimental)"
- AUTODETECT OFF
- CONDITION QT_FEATURE_xcb_xlib AND QT_FEATURE_fontconfig AND XRender_FOUND
- EMIT_IF QT_FEATURE_xcb
-)
-qt_feature("xrender" PRIVATE
- LABEL "XRender for native painting"
- CONDITION QT_FEATURE_xcb_native_painting
- EMIT_IF QT_FEATURE_xcb AND QT_FEATURE_xcb_native_painting
-)
qt_feature("xcb-xlib" PRIVATE
LABEL "XCB Xlib"
CONDITION QT_FEATURE_xlib AND X11_XCB_FOUND
diff --git a/src/gui/doc/src/richtext.qdoc b/src/gui/doc/src/richtext.qdoc
index 2fa49a31e03..f94c436bd80 100644
--- a/src/gui/doc/src/richtext.qdoc
+++ b/src/gui/doc/src/richtext.qdoc
@@ -1047,6 +1047,12 @@
\li \c type (\c 1, \c a, \c A, \c square, \c disc, \c circle)
\endlist
+ Additionally, the following attribute is supported by the \c ol tag:
+
+ \list
+ \li \c start
+ \endlist
+
\section1 Table Cell Attributes
The following attributes are supported by the \c td and \c th
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 6ba113ef8fb..4a8b409379c 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -47,6 +47,9 @@
#include <memory>
+#define QT_XFORM_TYPE_MSBFIRST 0
+#define QT_XFORM_TYPE_LSBFIRST 1
+
QT_BEGIN_NAMESPACE
class QCmyk32;
@@ -4447,6 +4450,8 @@ int QImage::metric(PaintDeviceMetric metric) const
trigx += m11; \
trigy += m12;
// END OF MACRO
+
+static
bool qt_xForm_helper(const QTransform &trueMat, int xoffset, int type, int depth,
uchar *dptr, qsizetype dbpl, int p_inc, int dHeight,
const uchar *sptr, qsizetype sbpl, int sWidth, int sHeight)
diff --git a/src/gui/image/qplatformpixmap.h b/src/gui/image/qplatformpixmap.h
index 5621afa4da5..3346ca85375 100644
--- a/src/gui/image/qplatformpixmap.h
+++ b/src/gui/image/qplatformpixmap.h
@@ -33,7 +33,7 @@ public:
enum ClassId { RasterClass, DirectFBClass,
BlitterClass, Direct2DClass,
- X11Class, CustomClass = 1024 };
+ CustomClass = 1024 };
QPlatformPixmap(PixelType pixelType, int classId);
virtual ~QPlatformPixmap();
@@ -111,7 +111,6 @@ protected:
private:
friend class QPixmap;
- friend class QX11PlatformPixmap;
friend class QImagePixmapCleanupHooks; // Needs to set is_cached
int detach_no;
@@ -122,10 +121,6 @@ private:
uint is_cached;
};
-# define QT_XFORM_TYPE_MSBFIRST 0
-# define QT_XFORM_TYPE_LSBFIRST 1
-Q_GUI_EXPORT bool qt_xForm_helper(const QTransform&, int, int, int, uchar*, qsizetype, int, int, const uchar*, qsizetype, int, int);
-
QT_END_NAMESPACE
#endif // QPLATFORMPIXMAP_H
diff --git a/src/gui/itemmodels/qfilesystemmodel.cpp b/src/gui/itemmodels/qfilesystemmodel.cpp
index 622c2e5bc92..9eb31f1b6d4 100644
--- a/src/gui/itemmodels/qfilesystemmodel.cpp
+++ b/src/gui/itemmodels/qfilesystemmodel.cpp
@@ -1787,14 +1787,17 @@ bool QFileSystemModel::event(QEvent *event)
bool QFileSystemModel::rmdir(const QModelIndex &aindex)
{
+ Q_D(QFileSystemModel);
+
QString path = filePath(aindex);
const bool success = QDir().rmdir(path);
-#if QT_CONFIG(filesystemwatcher)
if (success) {
- QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func());
+#if QT_CONFIG(filesystemwatcher)
d->fileInfoGatherer->removePath(path);
- }
#endif
+ QFileSystemModelPrivate::QFileSystemNode *parentNode = d->node(aindex.parent());
+ d->removeNode(parentNode, fileName(aindex));
+ }
return success;
}
diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp
index d27539b2419..c9df5d28a45 100644
--- a/src/gui/painting/qtextureglyphcache.cpp
+++ b/src/gui/painting/qtextureglyphcache.cpp
@@ -301,6 +301,8 @@ void QImageTextureGlyphCache::fillTexture(const Coord &c,
const QFixedPoint &subPixelPosition)
{
QImage mask = textureMapForGlyph(g, subPixelPosition);
+ if (mask.isNull())
+ return;
#ifdef CACHE_DEBUG
printf("fillTexture of %dx%d at %d,%d in the cache of %dx%d\n", c.w, c.h, c.x, c.y, m_image.width(), m_image.height());
diff --git a/src/gui/rhi/qrhigles2.cpp b/src/gui/rhi/qrhigles2.cpp
index 15f5cd8f7e8..81d2719117e 100644
--- a/src/gui/rhi/qrhigles2.cpp
+++ b/src/gui/rhi/qrhigles2.cpp
@@ -3959,6 +3959,7 @@ void QRhiGles2::executeCommandBuffer(QRhiCommandBuffer *cb)
break;
case QGles2CommandBuffer::Command::InvalidateFramebuffer:
if (caps.gles && caps.ctxMajor >= 3) {
+ f->glBindFramebuffer(GL_FRAMEBUFFER, cmd.args.invalidateFramebuffer.fbo);
f->glInvalidateFramebuffer(GL_DRAW_FRAMEBUFFER,
cmd.args.invalidateFramebuffer.attCount,
cmd.args.invalidateFramebuffer.att);
@@ -4881,6 +4882,7 @@ void QRhiGles2::endPass(QRhiCommandBuffer *cb, QRhiResourceUpdateBatch *resource
if (mayDiscardDepthStencil) {
QGles2CommandBuffer::Command &cmd(cbD->commands.get());
cmd.cmd = QGles2CommandBuffer::Command::InvalidateFramebuffer;
+ cmd.args.invalidateFramebuffer.fbo = rtTex->framebuffer;
if (caps.needsDepthStencilCombinedAttach) {
cmd.args.invalidateFramebuffer.attCount = 1;
cmd.args.invalidateFramebuffer.att[0] = GL_DEPTH_STENCIL_ATTACHMENT;
diff --git a/src/gui/rhi/qrhigles2_p.h b/src/gui/rhi/qrhigles2_p.h
index 725e71a3665..ea061f9d218 100644
--- a/src/gui/rhi/qrhigles2_p.h
+++ b/src/gui/rhi/qrhigles2_p.h
@@ -547,6 +547,7 @@ struct QGles2CommandBuffer : public QRhiCommandBuffer
GLbitfield barriers;
} barrier;
struct {
+ GLuint fbo;
int attCount;
GLenum att[3];
} invalidateFramebuffer;
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index d1509e4a251..75550439521 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -166,6 +166,7 @@ public:
QFontPrivate();
QFontPrivate(const QFontPrivate &other);
+ QFontPrivate &operator=(const QFontPrivate &) = delete;
~QFontPrivate();
QFontEngine *engineForScript(int script) const;
@@ -206,9 +207,6 @@ public:
void setVariableAxis(QFont::Tag tag, float value);
void unsetVariableAxis(QFont::Tag tag);
bool hasVariableAxis(QFont::Tag tag, float value) const;
-
-private:
- QFontPrivate &operator=(const QFontPrivate &) { return *this; }
};
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index 11c79f23d25..29fda652ef6 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
// Qt-Security score:critical reason:data-parser
+#include <QtCore/private/qflatmap_p.h>
#include <QtGui/private/qtguiglobal_p.h>
#include "qdebug.h"
#include "qtextformat.h"
@@ -1613,11 +1614,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
{
uint glyphs_shaped = 0;
- hb_buffer_t *buffer = hb_buffer_create();
- hb_buffer_set_unicode_funcs(buffer, hb_qt_get_unicode_funcs());
+ if (!buffer) {
+ buffer = hb_buffer_create();
+ hb_buffer_set_unicode_funcs(buffer, hb_qt_get_unicode_funcs());
+ }
+
hb_buffer_pre_allocate(buffer, itemLength);
if (Q_UNLIKELY(!hb_buffer_allocation_successful(buffer))) {
hb_buffer_destroy(buffer);
+ buffer = nullptr;
return 0;
}
@@ -1671,26 +1676,26 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
bool dontLigate = hasLetterSpacing && !scriptRequiresOpenType;
- QHash<QFont::Tag, quint32> features;
- features.insert(QFont::Tag("kern"), !!kerningEnabled);
+ QVarLengthFlatMap<QFont::Tag, hb_feature_t, 16> features;
+ auto insertFeature = [&features](QFont::Tag tag, quint32 value) {
+ features.insert(tag, { tag.value(),
+ value,
+ HB_FEATURE_GLOBAL_START,
+ HB_FEATURE_GLOBAL_END });
+ };
+ // fontFeatures have precedence
+ for (const auto &[tag, value]: fontFeatures.asKeyValueRange())
+ insertFeature(tag, value);
+ insertFeature(QFont::Tag("kern"), !!kerningEnabled);
if (dontLigate) {
- features.insert(QFont::Tag("liga"), false);
- features.insert(QFont::Tag("clig"), false);
- features.insert(QFont::Tag("dlig"), false);
- features.insert(QFont::Tag("hlig"), false);
- }
- features.insert(fontFeatures);
-
- QVarLengthArray<hb_feature_t, 16> featureArray;
- for (auto it = features.constBegin(); it != features.constEnd(); ++it) {
- featureArray.append({ it.key().value(),
- it.value(),
- HB_FEATURE_GLOBAL_START,
- HB_FEATURE_GLOBAL_END });
+ insertFeature(QFont::Tag("liga"), false);
+ insertFeature(QFont::Tag("clig"), false);
+ insertFeature(QFont::Tag("dlig"), false);
+ insertFeature(QFont::Tag("hlig"), false);
}
// whitelist cross-platforms shapers only
- static const char *shaper_list[] = {
+ constexpr const char *shaper_list[] = {
"graphite2",
"ot",
"fallback",
@@ -1699,13 +1704,11 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
bool shapedOk = hb_shape_full(hb_font,
buffer,
- featureArray.constData(),
- features.size(),
+ features.values().constData(),
+ features.values().size(),
shaper_list);
- if (Q_UNLIKELY(!shapedOk)) {
- hb_buffer_destroy(buffer);
+ if (Q_UNLIKELY(!shapedOk))
return 0;
- }
if (Q_UNLIKELY(HB_DIRECTION_IS_BACKWARD(props.direction)))
hb_buffer_reverse(buffer);
@@ -1718,10 +1721,8 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
num_glyphs = 1;
// ensure we have enough space for shaped glyphs and metrics
- if (Q_UNLIKELY(!ensureSpace(glyphs_shaped + num_glyphs))) {
- hb_buffer_destroy(buffer);
+ if (Q_UNLIKELY(!ensureSpace(glyphs_shaped + num_glyphs)))
return 0;
- }
// fetch the shaped glyphs and metrics
QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs);
@@ -1781,8 +1782,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
glyphs_shaped += num_glyphs;
}
- hb_buffer_destroy(buffer);
-
return glyphs_shaped;
}
@@ -1826,6 +1825,12 @@ QTextEngine::~QTextEngine()
delete layoutData;
delete specialData;
resetFontEngineCache();
+#if QT_CONFIG(harfbuzz)
+ if (buffer) {
+ hb_buffer_destroy(buffer);
+ buffer = nullptr;
+ }
+#endif
}
const QCharAttributes *QTextEngine::attributes() const
diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h
index dffbc129b3a..e513fd598ba 100644
--- a/src/gui/text/qtextengine_p.h
+++ b/src/gui/text/qtextengine_p.h
@@ -40,6 +40,8 @@
#include <stdlib.h>
#include <vector>
+struct hb_buffer_t;
+
QT_BEGIN_NAMESPACE
class QFontPrivate;
@@ -583,6 +585,8 @@ private:
void indexFormats();
void resolveFormats() const;
+ mutable hb_buffer_t *buffer = nullptr;
+
public:
bool atWordSeparator(int position) const;
diff --git a/src/network/access/qhttpnetworkrequest.cpp b/src/network/access/qhttpnetworkrequest.cpp
index 07f36df851c..c9d2b6f7b88 100644
--- a/src/network/access/qhttpnetworkrequest.cpp
+++ b/src/network/access/qhttpnetworkrequest.cpp
@@ -5,6 +5,8 @@
#include "qhttpnetworkrequest_p.h"
#include "private/qnoncontiguousbytedevice_p.h"
+#include <QtCore/private/qtools_p.h>
+
QT_BEGIN_NAMESPACE
QT_IMPL_METATYPE_EXTERN(QHttpNetworkRequest)
@@ -129,8 +131,19 @@ QByteArray QHttpNetworkRequestPrivate::header(const QHttpNetworkRequest &request
ba += QByteArray::number(request.minorVersion());
ba += "\r\n";
+ constexpr auto titlecase = [](QByteArrayView name) {
+ std::string n;
+ n.reserve(size_t(name.size()));
+ bool toUpperNext = true;
+ for (char c : name) {
+ n += toUpperNext ? QtMiscUtils::toAsciiUpper(c) : c;
+ toUpperNext = c == '-';
+ }
+ return n;
+ };
+
for (qsizetype i = 0; i < headers.size(); ++i) {
- ba += headers.nameAt(i);
+ ba += titlecase(headers.nameAt(i));
ba += ": ";
ba += headers.valueAt(i);
ba += "\r\n";
diff --git a/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp b/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp
index 62d24eefd33..e5ada714ba5 100644
--- a/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp
+++ b/src/plugins/networkinformation/glib/qglibnetworkinformationbackend.cpp
@@ -110,7 +110,8 @@ QGlibNetworkInformationBackend::QGlibNetworkInformationBackend()
connectivityHandlerId = g_signal_connect_swapped(networkMonitor, "notify::connectivity",
G_CALLBACK(updateConnectivity), this);
- networkHandlerId = g_signal_connect_swapped(networkMonitor, "network-changed",
+ // needed until GLib 2.86 for netlink support
+ networkHandlerId = g_signal_connect_swapped(networkMonitor, "notify::network-available",
G_CALLBACK(updateConnectivity), this);
meteredHandlerId = g_signal_connect_swapped(networkMonitor, "notify::network-metered",
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 08c9f5d5ba2..2989b4d6df3 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -161,6 +161,7 @@ static void populateRoleMap()
roleMap[QAccessible::Graphic] = NSAccessibilityImageRole;
roleMap[QAccessible::Tree] = NSAccessibilityOutlineRole;
roleMap[QAccessible::BlockQuote] = NSAccessibilityGroupRole;
+ roleMap[QAccessible::LayeredPane] = NSAccessibilityGroupRole;
}
/*
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 144c0519155..238f2ea2307 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -714,6 +714,25 @@ static void convertLineOffset(QAccessibleTextInterface *text, int *line, int *of
iface->setText(QAccessible::Description, QString::fromNSString(label));
}
+- (NSAccessibilityOrientation)accessibilityOrientation {
+ QAccessibleInterface *iface = self.qtInterface;
+ if (!iface)
+ return NSAccessibilityOrientationUnknown;
+
+ NSAccessibilityOrientation nsOrientation = NSAccessibilityOrientationUnknown;
+ if (QAccessibleAttributesInterface *attributesIface = iface->attributesInterface()) {
+ const QVariant orientationVariant =
+ attributesIface->attributeValue(QAccessible::Attribute::Orientation);
+ if (orientationVariant.isValid()) {
+ Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>());
+ const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>();
+ nsOrientation = orientation == Qt::Horizontal ? NSAccessibilityOrientationHorizontal
+ : NSAccessibilityOrientationVertical;
+ }
+ }
+ return nsOrientation;
+}
+
- (id) accessibilityValue {
if (QAccessibleInterface *iface = self.qtInterface) {
// VoiceOver asks for the value attribute for all elements. Return nil
diff --git a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
index e0ef6cec794..4c4e5fac962 100644
--- a/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
+++ b/src/plugins/platforms/cocoa/qcocoafiledialoghelper.mm
@@ -491,7 +491,7 @@ typedef QSharedPointer<QFileDialogOptions> SharedPointerFileDialogOptions;
return;
if (m_panel.visible) {
- const QString selection = QString::fromNSString(m_panel.URL.path);
+ const QString selection = QString::fromNSString(m_panel.URL.path).normalized(QString::NormalizationForm_C);
if (selection != m_currentSelection) {
m_currentSelection = selection;
emit m_helper->currentChanged(QUrl::fromLocalFile(selection));
diff --git a/src/plugins/platforms/ios/qiostheme.h b/src/plugins/platforms/ios/qiostheme.h
index b7ff3bb2a58..7af9cf80355 100644
--- a/src/plugins/platforms/ios/qiostheme.h
+++ b/src/plugins/platforms/ios/qiostheme.h
@@ -26,6 +26,7 @@ public:
Qt::ColorScheme colorScheme() const override;
void requestColorScheme(Qt::ColorScheme scheme) override;
+ Qt::ContrastPreference contrastPreference() const override;
#if !defined(Q_OS_TVOS) && !defined(Q_OS_VISIONOS)
QPlatformMenuItem* createPlatformMenuItem() const override;
diff --git a/src/plugins/platforms/ios/qiostheme.mm b/src/plugins/platforms/ios/qiostheme.mm
index cdf669f921c..435c21bf579 100644
--- a/src/plugins/platforms/ios/qiostheme.mm
+++ b/src/plugins/platforms/ios/qiostheme.mm
@@ -202,6 +202,12 @@ void QIOSTheme::requestColorScheme(Qt::ColorScheme scheme)
#endif
}
+Qt::ContrastPreference QIOSTheme::contrastPreference() const
+{
+ return UIAccessibilityDarkerSystemColorsEnabled() ? Qt::ContrastPreference::HighContrast : Qt::ContrastPreference::NoPreference;
+}
+
+
void QIOSTheme::applyTheme(UIWindow *window)
{
const UIUserInterfaceStyle style = []{
diff --git a/src/plugins/platforms/ios/quiwindow.mm b/src/plugins/platforms/ios/quiwindow.mm
index bb4268e1c88..62fd9c5d770 100644
--- a/src/plugins/platforms/ios/quiwindow.mm
+++ b/src/plugins/platforms/ios/quiwindow.mm
@@ -54,7 +54,9 @@
if (self.screen == UIScreen.mainScreen) {
// Check if the current userInterfaceStyle reports a different appearance than
// the platformTheme's appearance. We might have set that one based on the UIScreen
+ // Check for changes in the "Increase contrast" setting too.
if (previousTraitCollection.userInterfaceStyle != self.traitCollection.userInterfaceStyle
+ || previousTraitCollection.accessibilityContrast != self.traitCollection.accessibilityContrast
|| QGuiApplicationPrivate::platformTheme()->colorScheme() != colorScheme) {
QIOSTheme::initializeSystemPalette();
QWindowSystemInterface::handleThemeChange<QWindowSystemInterface::SynchronousDelivery>();
diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.cpp b/src/plugins/platforms/wasm/qwasmaccessibility.cpp
index 5fa79482217..5807d157636 100644
--- a/src/plugins/platforms/wasm/qwasmaccessibility.cpp
+++ b/src/plugins/platforms/wasm/qwasmaccessibility.cpp
@@ -401,6 +401,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
case QAccessible::PageTabList:{
element = document.call<emscripten::val>("createElement", std::string("div"));
setAttribute(element, "role", "tablist");
+ setHtmlElementOrientation(element, iface);
m_elements[iface] = element;
@@ -423,6 +424,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
element = document.call<emscripten::val>("createElement", std::string("div"));
setAttribute(element, "role", "scrollbar");
setAttribute(element, "aria-valuenow", valueString);
+ setHtmlElementOrientation(element, iface);
addEventListener(iface, element, "change");
} break;
@@ -437,6 +439,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
element = document.call<emscripten::val>("createElement", std::string("div"));
setAttribute(element, "role", "toolbar");
setAttribute(element, "title", text.toStdString());
+ setHtmlElementOrientation(element, iface);
addEventListener(iface, element, "click");
}break;
case QAccessible::MenuItem:
@@ -453,6 +456,7 @@ emscripten::val QWasmAccessibility::createHtmlElement(QAccessibleInterface *ifac
element = document.call<emscripten::val>("createElement", std::string("div"));
setAttribute(element, "role", "menubar");
setAttribute(element, "title", text.toStdString());
+ setHtmlElementOrientation(element, iface);
m_elements[iface] = element;
for (int i = 0; i < iface->childCount(); ++i) {
@@ -582,14 +586,7 @@ void QWasmAccessibility::linkToParent(QAccessibleInterface *iface)
void QWasmAccessibility::setHtmlElementVisibility(QAccessibleInterface *iface, bool visible)
{
emscripten::val element = getHtmlElement(iface);
-
- if (visible) {
- setAttribute(element, "aria-hidden", false);
- setAttribute(element, "tabindex", "");
- } else {
- setAttribute(element, "aria-hidden", true); // aria-hidden mean completely hidden; maybe some sort of soft-hidden should be used.
- setAttribute(element, "tabindex", "-1");
- }
+ setAttribute(element, "aria-hidden", !visible);
}
void QWasmAccessibility::setHtmlElementGeometry(QAccessibleInterface *iface)
@@ -661,6 +658,21 @@ void QWasmAccessibility::setHtmlElementDisabled(QAccessibleInterface *iface)
setAttribute(element, "aria-disabled", iface->state().disabled);
}
+void QWasmAccessibility::setHtmlElementOrientation(emscripten::val element, QAccessibleInterface *iface)
+{
+ Q_ASSERT(iface);
+ if (QAccessibleAttributesInterface *attributesIface = iface->attributesInterface()) {
+ const QVariant orientationVariant =
+ attributesIface->attributeValue(QAccessible::Attribute::Orientation);
+ if (orientationVariant.isValid()) {
+ Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>());
+ const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>();
+ const std::string value = orientation == Qt::Horizontal ? "horizontal" : "vertical";
+ setAttribute(element, "aria-orientation", value);
+ }
+ }
+}
+
void QWasmAccessibility::handleStaticTextUpdate(QAccessibleEvent *event)
{
switch (event->type()) {
diff --git a/src/plugins/platforms/wasm/qwasmaccessibility.h b/src/plugins/platforms/wasm/qwasmaccessibility.h
index 26f3e0e9afe..ddbfec918d6 100644
--- a/src/plugins/platforms/wasm/qwasmaccessibility.h
+++ b/src/plugins/platforms/wasm/qwasmaccessibility.h
@@ -77,6 +77,7 @@ private:
void setHtmlElementTextNameLE(QAccessibleInterface *iface);
void setHtmlElementFocus(QAccessibleInterface *iface);
void setHtmlElementDisabled(QAccessibleInterface *iface);
+ void setHtmlElementOrientation(emscripten::val element, QAccessibleInterface *iface);
void handleStaticTextUpdate(QAccessibleEvent *event);
void handleButtonUpdate(QAccessibleEvent *event);
diff --git a/src/plugins/platforms/wasm/qwasminputcontext.cpp b/src/plugins/platforms/wasm/qwasminputcontext.cpp
index 18a457198f1..a0546fdc215 100644
--- a/src/plugins/platforms/wasm/qwasminputcontext.cpp
+++ b/src/plugins/platforms/wasm/qwasminputcontext.cpp
@@ -40,8 +40,23 @@ void QWasmInputContext::inputCallback(emscripten::val event)
// Some of them should be implemented here later.
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "inputType : " << inputTypeString;
if (!inputTypeString.compare("deleteContentBackward")) {
- QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier);
- QWindowSystemInterface::handleKeyEvent(0, QEvent::KeyRelease, Qt::Key_Backspace, Qt::NoModifier);
+
+ QInputMethodQueryEvent queryEvent(Qt::ImQueryAll);
+ QCoreApplication::sendEvent(m_focusObject, &queryEvent);
+ int cursorPosition = queryEvent.value(Qt::ImCursorPosition).toInt();
+
+ int deleteLength = rangesPair.second - rangesPair.first;
+ int deleteFrom = -1;
+ if (cursorPosition > rangesPair.first) {
+ deleteFrom = -(cursorPosition - rangesPair.first);
+ }
+ QInputMethodEvent e;
+ e.setCommitString(QString(), deleteFrom, deleteLength);
+ QCoreApplication::sendEvent(m_focusObject, &e);
+
+ rangesPair.first = 0;
+ rangesPair.second = 0;
+
event.call<void>("stopImmediatePropagation");
return;
} else if (!inputTypeString.compare("deleteContentForward")) {
@@ -138,41 +153,23 @@ void QWasmInputContext::compositionUpdateCallback(emscripten::val event)
const auto compositionStr = QString::fromEcmaString(event["data"]);
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << compositionStr;
- // WA for IOS.
- // Not sure now because I cannot test it anymore.
-// int replaceSize = 0;
-// emscripten::val win = emscripten::val::global("window");
-// emscripten::val sel = win.call<emscripten::val>("getSelection");
-// if (!sel.isNull() && !sel.isUndefined()
-// && sel["rangeCount"].as<int>() > 0) {
-// QInputMethodQueryEvent queryEvent(Qt::ImQueryAll);
-// QCoreApplication::sendEvent(QGuiApplication::focusObject(), &queryEvent);
-// qCDebug(qLcQpaWasmInputContext) << "Qt surrounding text: " << queryEvent.value(Qt::ImSurroundingText).toString();
-// qCDebug(qLcQpaWasmInputContext) << "Qt current selection: " << queryEvent.value(Qt::ImCurrentSelection).toString();
-// qCDebug(qLcQpaWasmInputContext) << "Qt text before cursor: " << queryEvent.value(Qt::ImTextBeforeCursor).toString();
-// qCDebug(qLcQpaWasmInputContext) << "Qt text after cursor: " << queryEvent.value(Qt::ImTextAfterCursor).toString();
-//
-// const QString &selectedStr = QString::fromEcmaString(sel.call<emscripten::val>("toString"));
-// const auto &preeditStr = preeditString();
-// qCDebug(qLcQpaWasmInputContext) << "Selection.type : " << sel["type"].as<std::string>();
-// qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "Selected: " << selectedStr;
-// qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "PreeditString: " << preeditStr;
-// if (!sel["type"].as<std::string>().compare("Range")) {
-// QString surroundingTextBeforeCursor = queryEvent.value(Qt::ImTextBeforeCursor).toString();
-// if (surroundingTextBeforeCursor.endsWith(selectedStr)) {
-// replaceSize = selectedStr.size();
-// qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO << "Current Preedit: " << preeditStr << replaceSize;
-// }
-// }
-// emscripten::val range = sel.call<emscripten::val>("getRangeAt", 0);
-// qCDebug(qLcQpaWasmInputContext) << "Range.startOffset : " << range["startOffset"].as<int>();
-// qCDebug(qLcQpaWasmInputContext) << "Range.endOffset : " << range["endOffset"].as<int>();
-// }
-//
-// setPreeditString(compositionStr, replaceSize);
setPreeditString(compositionStr, 0);
}
+void QWasmInputContext::beforeInputCallback(emscripten::val event)
+{
+ emscripten::val ranges = event.call<emscripten::val>("getTargetRanges");
+
+ auto length = ranges["length"].as<int>();
+ for (auto i = 0; i < length; i++) {
+ emscripten::val range = ranges[i];
+ qCDebug(qLcQpaWasmInputContext) << "startOffset" << range["startOffset"].as<int>();
+ qCDebug(qLcQpaWasmInputContext) << "endOffset" << range["endOffset"].as<int>();
+ rangesPair.first = range["startOffset"].as<int>();
+ rangesPair.second = range["endOffset"].as<int>();
+ }
+}
+
QWasmInputContext::QWasmInputContext()
{
qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
diff --git a/src/plugins/platforms/wasm/qwasminputcontext.h b/src/plugins/platforms/wasm/qwasminputcontext.h
index 6d24c7fea0d..97415451b2a 100644
--- a/src/plugins/platforms/wasm/qwasminputcontext.h
+++ b/src/plugins/platforms/wasm/qwasminputcontext.h
@@ -45,6 +45,7 @@ public:
void compositionEndCallback(emscripten::val event);
void compositionStartCallback(emscripten::val event);
void compositionUpdateCallback(emscripten::val event);
+ void beforeInputCallback(emscripten::val event);
void updateGeometry();
@@ -62,6 +63,7 @@ private:
bool m_inputMethodAccepted = false;
QObject *m_focusObject = nullptr;
emscripten::val m_inputElement = emscripten::val::null();
+ QPair<int, int> rangesPair;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
index 04f52ac9b1b..e49c1dc49f1 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.cpp
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -110,6 +110,7 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
// Set up m_inputElement, which takes focus whenever a Qt text input UI element has
// foucus.
m_inputElement["classList"].call<void>("add", emscripten::val("qt-window-input-element"));
+ m_inputElement.call<void>("setAttribute", std::string("contenteditable"), std::string("true"));
m_inputElement.set("type", "text");
m_inputElement["style"].set("position", "absolute");
m_inputElement["style"].set("left", 0);
@@ -227,6 +228,8 @@ void QWasmWindow::registerEventHandlers()
[this](emscripten::val event){ handleCompositionStartEvent(event); });
m_compositionEndCallback = QWasmEventHandler(m_window, "compositionend",
[this](emscripten::val event){ handleCompositionEndEvent(event); });
+ m_beforeInputCallback = QWasmEventHandler(m_window, "beforeinput",
+ [this](emscripten::val event){ handleBeforeInputEvent(event); });
}
QWasmWindow::~QWasmWindow()
@@ -789,6 +792,16 @@ void QWasmWindow::handleCompositionEndEvent(emscripten::val event)
m_focusHelper.set("innerHTML", std::string());
}
+void QWasmWindow::handleBeforeInputEvent(emscripten::val event)
+{
+ qWarning() << Q_FUNC_INFO;
+
+ if (QWasmInputContext *inputContext = QWasmIntegration::get()->wasmInputContext(); inputContext->isActive())
+ inputContext->beforeInputCallback(event);
+ // else
+ // m_focusHelper.set("innerHTML", std::string());
+}
+
void QWasmWindow::handlePointerEnterLeaveEvent(const PointerEvent &event)
{
if (processPointerEnterLeave(event))
diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h
index cbe930dce89..8e6e5021dcf 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.h
+++ b/src/plugins/platforms/wasm/qwasmwindow.h
@@ -145,6 +145,7 @@ private:
void handleCompositionStartEvent(emscripten::val event);
void handleCompositionUpdateEvent(emscripten::val event);
void handleCompositionEndEvent(emscripten::val event);
+ void handleBeforeInputEvent(emscripten::val event);
void handlePointerEnterLeaveEvent(const PointerEvent &event);
bool processPointerEnterLeave(const PointerEvent &event);
@@ -183,6 +184,7 @@ private:
QWasmEventHandler m_compositionStartCallback;
QWasmEventHandler m_compositionUpdateCallback;
QWasmEventHandler m_compositionEndCallback;
+ QWasmEventHandler m_beforeInputCallback;
QWasmEventHandler m_pointerDownCallback;
QWasmEventHandler m_pointerMoveCallback;
diff --git a/src/plugins/platforms/wayland/CMakeLists.txt b/src/plugins/platforms/wayland/CMakeLists.txt
index 7e3589def6b..0ce9a4b091c 100644
--- a/src/plugins/platforms/wayland/CMakeLists.txt
+++ b/src/plugins/platforms/wayland/CMakeLists.txt
@@ -17,14 +17,6 @@ qt_internal_add_module(WaylandGlobalPrivate
NO_GENERATE_CPP_EXPORTS
)
-# Work around 115101.
-# If nothing depends on the WaylandGlobalPrivate target it doesn't run custom commands that the
-# target depends on. WaylandGlobalPrivate_ensure_sync_headers makes sure that 'all' depends on
-# WaylandGlobalPrivate_sync_headers.
-# TODO: This needs to be removed once the fix for QTBUG-115101 is merged in qtbase.
-add_custom_target(WaylandGlobalPrivate_ensure_sync_headers ALL)
-add_dependencies(WaylandGlobalPrivate_ensure_sync_headers WaylandGlobalPrivate_sync_headers)
-
# special case begin
# TODO: Ideally these macros would be part of the qtwaylandscanner tool, and not the compositor/client
include(../../../../src/tools/qtwaylandscanner/Qt6WaylandClientMacros.cmake)
diff --git a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp
index 84ecc289c59..9aa8af39090 100644
--- a/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp
+++ b/src/plugins/platforms/wayland/plugins/shellintegration/xdg-shell/qwaylandxdgtopleveliconv1.cpp
@@ -2,7 +2,6 @@
// Copyright (C) 2024 David Edmundson <[email protected]>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-#include "qwaylandshmbackingstore_p.h"
#include "qwaylandxdgtopleveliconv1_p.h"
#include <QtWaylandClient/private/qwaylanddisplay_p.h>
diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
index 6ce43714a35..34b32da289c 100644
--- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
+++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp
@@ -729,11 +729,11 @@ public:
void QWaylandInputDevice::Pointer::pointer_leave(uint32_t serial, struct wl_surface *surface)
{
+ Q_UNUSED(serial);
+
invalidateFocus();
mButtons = Qt::NoButton;
- mParent->mSerial = serial;
-
// The event may arrive after destroying the window, indicated by
// a null surface.
if (!surface)
diff --git a/src/plugins/platforms/windows/qwindowsiconengine.cpp b/src/plugins/platforms/windows/qwindowsiconengine.cpp
index 71103183183..edc1ea3a9dc 100644
--- a/src/plugins/platforms/windows/qwindowsiconengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsiconengine.cpp
@@ -63,8 +63,8 @@ static QString getGlyphs(QStringView iconName)
{"go-home"_L1, u"\ue80f"},
// {"go-jump"_L1, u"\uf719"},
//{"go-last"_L1, u"\ue5dd"},
- {"go-next"_L1, u"\ue893"},
- {"go-previous"_L1, u"\ue892"},
+ {"go-next"_L1, u"\ue72a"},
+ {"go-previous"_L1, u"\ue72b"},
//{"go-top"_L1, u"\ue25a"},
{"go-up"_L1, u"\ue74a"},
{"help-about"_L1, u"\ue946"},
@@ -100,7 +100,7 @@ static QString getGlyphs(QStringView iconName)
//{"object-flip-vertical"_L1, u"\u"},
{"object-rotate-left"_L1, u"\ue80c"},
{"object-rotate-right"_L1, u"\ue80d"},
- //{"process-stop"_L1, u"\ue5c9"},
+ {"process-stop"_L1, u"\uf140"},
{"system-lock-screen"_L1, u"\uee3f"},
{"system-log-out"_L1, u"\uf3b1"},
//{"system-run"_L1, u"\u"},
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 53548622dfc..7908f22d99d 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -553,12 +553,14 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData)
const bool orientationChanged = m_data.orientation != newData.orientation;
const bool primaryChanged = (newData.flags & QWindowsScreenData::PrimaryScreen)
&& !(m_data.flags & QWindowsScreenData::PrimaryScreen);
+ const bool refreshRateChanged = m_data.refreshRateHz != newData.refreshRateHz;
m_data.dpi = newData.dpi;
m_data.orientation = newData.orientation;
m_data.geometry = newData.geometry;
m_data.availableGeometry = newData.availableGeometry;
m_data.flags = (m_data.flags & ~QWindowsScreenData::PrimaryScreen)
| (newData.flags & QWindowsScreenData::PrimaryScreen);
+ m_data.refreshRateHz = newData.refreshRateHz;
if (dpiChanged) {
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen(),
@@ -573,6 +575,9 @@ void QWindowsScreen::handleChanges(const QWindowsScreenData &newData)
}
if (primaryChanged)
QWindowSystemInterface::handlePrimaryScreenChanged(this);
+
+ if (refreshRateChanged)
+ QWindowSystemInterface::handleScreenRefreshRateChange(screen(), newData.refreshRateHz);
}
HMONITOR QWindowsScreen::handle() const
@@ -869,9 +874,8 @@ const QWindowsScreen *QWindowsScreenManager::screenAtDp(const QPoint &p) const
return nullptr;
}
-const QWindowsScreen *QWindowsScreenManager::screenForHwnd(HWND hwnd) const
+const QWindowsScreen *QWindowsScreenManager::screenForMonitor(HMONITOR hMonitor) const
{
- HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
if (hMonitor == nullptr)
return nullptr;
const auto it =
@@ -884,4 +888,18 @@ const QWindowsScreen *QWindowsScreenManager::screenForHwnd(HWND hwnd) const
return it != m_screens.cend() ? *it : nullptr;
}
+const QWindowsScreen *QWindowsScreenManager::screenForHwnd(HWND hwnd) const
+{
+ HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
+ return screenForMonitor(hMonitor);
+}
+
+const QWindowsScreen *QWindowsScreenManager::screenForRect(const RECT *rect) const
+{
+ if (rect == nullptr)
+ return nullptr;
+ HMONITOR hMonitor = MonitorFromRect(rect, MONITOR_DEFAULTTONULL);
+ return screenForMonitor(hMonitor);
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 8d555998388..0032fd462cb 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -115,12 +115,14 @@ public:
const QWindowsScreen *screenAtDp(const QPoint &p) const;
const QWindowsScreen *screenForHwnd(HWND hwnd) const;
+ const QWindowsScreen *screenForRect(const RECT *rect) const;
static bool isSingleScreen();
private:
void addScreen(const QWindowsScreenData &screenData);
void removeScreen(int index);
+ const QWindowsScreen *screenForMonitor(HMONITOR monitor) const;
HWND m_displayChangeObserver = nullptr;
WindowsScreenList m_screens;
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 01716fba60c..72daffb56b1 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -466,15 +466,17 @@ static bool applyBlurBehindWindow(HWND hwnd)
return result;
}
+static bool shouldShowTitlebarButton(Qt::WindowFlags flags, Qt::WindowFlags button)
+{
+ return !flags.testFlag(Qt::CustomizeWindowHint) || flags.testFlags(Qt::CustomizeWindowHint | button);
+}
+
// from qwidget_win.cpp, pass flags separately in case they have been "autofixed".
static bool shouldShowMaximizeButton(const QWindow *w, Qt::WindowFlags flags)
{
- if ((flags & Qt::MSWindowsFixedSizeDialogHint) || !(flags & Qt::WindowMaximizeButtonHint))
- return false;
- // if the user explicitly asked for the maximize button, we try to add
- // it even if the window has fixed size.
- return (flags & Qt::CustomizeWindowHint) ||
- w->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX);
+ return !flags.testFlag(Qt::MSWindowsFixedSizeDialogHint) &&
+ (shouldShowTitlebarButton(flags, Qt::WindowMaximizeButtonHint) ||
+ w->maximumSize() == QSize(QWINDOWSIZE_MAX, QWINDOWSIZE_MAX));
}
bool QWindowsWindow::hasNoNativeFrame(HWND hwnd, Qt::WindowFlags flags)
@@ -805,6 +807,7 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
if (topLevel) {
if ((type == Qt::Window || dialog || tool)) {
+ const bool defaultTitlebar = !flags.testFlag(Qt::CustomizeWindowHint);
if (!(flags & Qt::FramelessWindowHint)) {
style |= WS_POPUP;
if (flags & Qt::MSWindowsFixedSizeDialogHint) {
@@ -812,16 +815,16 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
} else {
style |= WS_THICKFRAME;
}
- if (flags & Qt::WindowTitleHint)
+ if (defaultTitlebar || flags.testFlags(Qt::CustomizeWindowHint | Qt::WindowTitleHint))
style |= WS_CAPTION; // Contains WS_DLGFRAME
}
- if (flags & Qt::WindowSystemMenuHint)
+ if (defaultTitlebar || flags.testFlags(Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint))
style |= WS_SYSMENU;
- else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
+ else if (dialog && (defaultTitlebar || flags.testFlags(Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint)) && !(flags & Qt::FramelessWindowHint)) {
style |= WS_SYSMENU | WS_BORDER; // QTBUG-2027, dialogs without system menu.
exStyle |= WS_EX_DLGMODALFRAME;
}
- const bool showMinimizeButton = flags & Qt::WindowMinimizeButtonHint;
+ const bool showMinimizeButton = shouldShowTitlebarButton(flags, Qt::WindowMinimizeButtonHint);
if (showMinimizeButton)
style |= WS_MINIMIZEBOX;
const bool showMaximizeButton = shouldShowMaximizeButton(w, flags);
@@ -2113,7 +2116,8 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
QWindowsThemeCache::clearThemeCache(hwnd);
// Send screen change first, so that the new screen is set during any following resize
- checkForScreenChanged(QWindowsWindow::FromDpiChange);
+ const auto prcNewWindow = reinterpret_cast<const RECT *>(lParam);
+ checkForScreenChanged(QWindowsWindow::FromDpiChange, !m_inSetgeometry ? prcNewWindow : nullptr);
if (!IsZoomed(hwnd))
m_data.restoreGeometry.setSize(m_data.restoreGeometry.size() * scale);
@@ -2136,7 +2140,6 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
// making the SetWindowPos() call.
if (!m_inSetgeometry) {
updateFullFrameMargins();
- const auto prcNewWindow = reinterpret_cast<RECT *>(lParam);
SetWindowPos(hwnd, nullptr, prcNewWindow->left, prcNewWindow->top,
prcNewWindow->right - prcNewWindow->left,
prcNewWindow->bottom - prcNewWindow->top, SWP_NOZORDER | SWP_NOACTIVATE);
@@ -2351,14 +2354,15 @@ static inline bool equalDpi(const QDpi &d1, const QDpi &d2)
return qFuzzyCompare(d1.first, d2.first) && qFuzzyCompare(d1.second, d2.second);
}
-void QWindowsWindow::checkForScreenChanged(ScreenChangeMode mode)
+void QWindowsWindow::checkForScreenChanged(ScreenChangeMode mode, const RECT *suggestedRect)
{
if ((parent() && !parent()->isForeignWindow()) || QWindowsScreenManager::isSingleScreen())
return;
QPlatformScreen *currentScreen = screen();
auto topLevel = isTopLevel_sys() ? m_data.hwnd : GetAncestor(m_data.hwnd, GA_ROOT);
- const QWindowsScreen *newScreen =
+ const QWindowsScreen *newScreen = suggestedRect ?
+ QWindowsContext::instance()->screenManager().screenForRect(suggestedRect) :
QWindowsContext::instance()->screenManager().screenForHwnd(topLevel);
if (newScreen == nullptr || newScreen == currentScreen)
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 499b2a9ca86..ee348f1ac16 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -342,7 +342,7 @@ public:
void stopAlertWindow();
enum ScreenChangeMode { FromGeometryChange, FromDpiChange, FromScreenAdded };
- void checkForScreenChanged(ScreenChangeMode mode = FromGeometryChange);
+ void checkForScreenChanged(ScreenChangeMode mode = FromGeometryChange, const RECT *suggestedRect = nullptr);
void registerTouchWindow();
static void setHasBorderInFullScreenStatic(QWindow *window, bool border);
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
index 0144786ce5e..b7bf97f5c4b 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiamainprovider.cpp
@@ -654,6 +654,21 @@ HRESULT QWindowsUiaMainProvider::GetPropertyValue(PROPERTYID idProp, VARIANT *pR
*pRetVal = QComVariant{ name }.release();
break;
}
+ case UIA_OrientationPropertyId: {
+ OrientationType orientationType = OrientationType_None;
+ if (QAccessibleAttributesInterface *attributesIface = accessible->attributesInterface()) {
+ const QVariant orientationVariant =
+ attributesIface->attributeValue(QAccessible::Attribute::Orientation);
+ if (orientationVariant.isValid()) {
+ Q_ASSERT(orientationVariant.canConvert<Qt::Orientation>());
+ const Qt::Orientation orientation = orientationVariant.value<Qt::Orientation>();
+ orientationType = orientation == Qt::Horizontal ? OrientationType_Horizontal
+ : OrientationType_Vertical;
+ }
+ }
+ *pRetVal = QComVariant{ long(orientationType) }.release();
+ break;
+ }
case UIA_StyleIdAttributeId:
setStyle(accessible, pRetVal);
break;
diff --git a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
index b2675d5b884..835499d3554 100644
--- a/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
+++ b/src/plugins/platforms/windows/uiautomation/qwindowsuiautils.cpp
@@ -154,6 +154,7 @@ long roleToControlTypeId(QAccessible::Role role)
{QAccessible::WebDocument, UIA_DocumentControlTypeId},
{QAccessible::Heading, UIA_TextControlTypeId},
{QAccessible::BlockQuote, UIA_GroupControlTypeId},
+ {QAccessible::LayeredPane, UIA_PaneControlTypeId},
};
long controlType = mapping.value(role, UIA_CustomControlTypeId);
diff --git a/src/plugins/platforms/xcb/CMakeLists.txt b/src/plugins/platforms/xcb/CMakeLists.txt
index 492d274c2fd..204acd72ba0 100644
--- a/src/plugins/platforms/xcb/CMakeLists.txt
+++ b/src/plugins/platforms/xcb/CMakeLists.txt
@@ -120,30 +120,6 @@ qt_internal_extend_target(XcbQpaPrivate CONDITION CLANG
-ftemplate-depth=1024
)
-qt_internal_extend_target(XcbQpaPrivate CONDITION QT_FEATURE_xcb_native_painting
- SOURCES
- nativepainting/qbackingstore_x11.cpp nativepainting/qbackingstore_x11_p.h
- nativepainting/qcolormap_x11.cpp nativepainting/qcolormap_x11_p.h
- nativepainting/qpaintengine_x11.cpp nativepainting/qpaintengine_x11_p.h
- nativepainting/qpixmap_x11.cpp nativepainting/qpixmap_x11_p.h
- nativepainting/qpolygonclipper_p.h
- nativepainting/qt_x11_p.h
- nativepainting/qtessellator.cpp nativepainting/qtessellator_p.h
- nativepainting/qxcbnativepainting.cpp nativepainting/qxcbnativepainting.h
- INCLUDE_DIRECTORIES
- nativepainting
-)
-
-qt_internal_extend_target(XcbQpaPrivate CONDITION QT_FEATURE_xcb_native_painting AND QT_FEATURE_xrender
- PUBLIC_LIBRARIES
- PkgConfig::XRender
-)
-
-qt_internal_extend_target(XcbQpaPrivate CONDITION QT_FEATURE_fontconfig AND QT_FEATURE_xcb_native_painting
- LIBRARIES
- WrapFreetype::WrapFreetype
-)
-
if(QT_FEATURE_system_xcb_xinput)
qt_internal_extend_target(XcbQpaPrivate LIBRARIES XCB::XINPUT)
else()
diff --git a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp
deleted file mode 100644
index 1ac5f6a64bc..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#include "qbackingstore_x11_p.h"
-#include "qxcbwindow.h"
-#include "qpixmap_x11_p.h"
-
-#include <private/qhighdpiscaling_p.h>
-#include <QPainter>
-
-#if QT_CONFIG(xrender)
-# include <X11/extensions/Xrender.h>
-#endif
-
-#define register /* C++17 deprecated register */
-#include <X11/Xlib.h>
-#undef register
-
-QT_BEGIN_NAMESPACE
-
-QXcbNativeBackingStore::QXcbNativeBackingStore(QWindow *window)
- : QPlatformBackingStore(window)
- , m_translucentBackground(false)
-{
- if (QXcbWindow *w = static_cast<QXcbWindow *>(window->handle())) {
- m_translucentBackground = w->connection()->hasXRender() &&
- QImage::toPixelFormat(w->imageFormat()).alphaUsage() == QPixelFormat::UsesAlpha;
- }
-}
-
-QXcbNativeBackingStore::~QXcbNativeBackingStore()
-{}
-
-QPaintDevice *QXcbNativeBackingStore::paintDevice()
-{
- return &m_pixmap;
-}
-
-void QXcbNativeBackingStore::flush(QWindow *window, const QRegion &region, const QPoint &offset)
-{
- if (m_pixmap.isNull())
- return;
-
- QSize pixmapSize = m_pixmap.size();
-
- QRegion clipped = region;
- clipped &= QRect(QPoint(), QHighDpi::toNativePixels(window->size(), window));
- clipped &= QRect(0, 0, pixmapSize.width(), pixmapSize.height()).translated(-offset);
-
- QRect br = clipped.boundingRect();
- if (br.isNull())
- return;
-
- QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
- if (!platformWindow) {
- qWarning("QXcbBackingStore::flush: QWindow has no platform window (QTBUG-32681)");
- return;
- }
-
- Window wid = platformWindow->xcb_window();
- Pixmap pid = qt_x11PixmapHandle(m_pixmap);
-
- QList<XRectangle> clipRects = qt_region_to_xrectangles(clipped);
-
-#if QT_CONFIG(xrender)
- if (m_translucentBackground)
- {
- XWindowAttributes attrib;
- XGetWindowAttributes(display(), wid, &attrib);
- XRenderPictFormat *format = XRenderFindVisualFormat(display(), attrib.visual);
-
- Picture srcPic = qt_x11PictureHandle(m_pixmap);
- Picture dstPic = XRenderCreatePicture(display(), wid, format, 0, 0);
-
- XRenderSetPictureClipRectangles(display(), dstPic, 0, 0, clipRects.constData(), clipRects.size());
-
- XRenderComposite(display(), PictOpSrc, srcPic, 0L /*None*/, dstPic, br.x() + offset.x(),
- br.y() + offset.y(), 0, 0, br.x(), br.y(), br.width(), br.height());
-
- XRenderFreePicture(display(), dstPic);
- }
- else
-#endif
- {
- GC gc = XCreateGC(display(), wid, 0, nullptr);
-
- if (clipRects.size() != 1)
- XSetClipRectangles(display(), gc, 0, 0, clipRects.data(), clipRects.size(), YXBanded);
-
- XCopyArea(display(), pid, wid, gc, br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), br.x(), br.y());
- XFreeGC(display(), gc);
- }
-
-
- if (platformWindow->needsSync()) {
- platformWindow->updateSyncRequestCounter();
- } else {
- XFlush(display());
- }
-}
-
-QImage QXcbNativeBackingStore::toImage() const
-{
- return m_pixmap.toImage();
-}
-
-void QXcbNativeBackingStore::resize(const QSize &size, const QRegion &staticContents)
-{
- if (size == m_pixmap.size())
- return;
-
- QPixmap newPixmap(size);
-
-#if QT_CONFIG(xrender)
- if (m_translucentBackground && newPixmap.depth() != 32)
- qt_x11Pixmap(newPixmap)->convertToARGB32();
-#endif
-
- if (!m_pixmap.isNull()) {
- Pixmap from = qt_x11PixmapHandle(m_pixmap);
- Pixmap to = qt_x11PixmapHandle(newPixmap);
- QRect br = staticContents.boundingRect().intersected(QRect(QPoint(0, 0), size));
-
- if (!br.isEmpty()) {
- GC gc = XCreateGC(display(), to, 0, nullptr);
- XCopyArea(display(), from, to, gc, br.x(), br.y(), br.width(), br.height(), br.x(), br.y());
- XFreeGC(display(), gc);
- }
- }
-
- m_pixmap = newPixmap;
-}
-
-bool QXcbNativeBackingStore::scroll(const QRegion &area, int dx, int dy)
-{
- if (m_pixmap.isNull())
- return false;
-
- QRect rect = area.boundingRect();
- Pixmap pix = qt_x11PixmapHandle(m_pixmap);
-
- GC gc = XCreateGC(display(), pix, 0, nullptr);
- XCopyArea(display(), pix, pix, gc,
- rect.x(), rect.y(), rect.width(), rect.height(),
- rect.x()+dx, rect.y()+dy);
- XFreeGC(display(), gc);
- return true;
-}
-
-void QXcbNativeBackingStore::beginPaint(const QRegion &region)
-{
- QX11PlatformPixmap *x11pm = qt_x11Pixmap(m_pixmap);
- if (x11pm)
- x11pm->setIsBackingStore(true);
-
-#if QT_CONFIG(xrender)
- if (m_translucentBackground) {
- const QList<XRectangle> xrects = qt_region_to_xrectangles(region);
- const XRenderColor color = { 0, 0, 0, 0 };
- XRenderFillRectangles(display(), PictOpSrc,
- qt_x11PictureHandle(m_pixmap), &color,
- xrects.constData(), xrects.size());
- }
-#else
- Q_UNUSED(region);
-#endif
-}
-
-Display *QXcbNativeBackingStore::display() const
-{
- return static_cast<Display *>(static_cast<QXcbWindow *>(window()->handle())->connection()->xlib_display());
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11_p.h
deleted file mode 100644
index b730b076d3f..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qbackingstore_x11_p.h
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-#include <qpa/qplatformbackingstore.h>
-
-typedef struct _XDisplay Display;
-
-QT_BEGIN_NAMESPACE
-
-class QXcbWindow;
-
-class QXcbNativeBackingStore : public QPlatformBackingStore
-{
-public:
- QXcbNativeBackingStore(QWindow *window);
- ~QXcbNativeBackingStore();
-
- QPaintDevice *paintDevice() override;
- void flush(QWindow *window, const QRegion &region, const QPoint &offset) override;
-
- QImage toImage() const override;
-
- void resize(const QSize &size, const QRegion &staticContents) override;
- bool scroll(const QRegion &area, int dx, int dy) override;
-
- void beginPaint(const QRegion &region) override;
-
-private:
- Display *display() const;
-
- QPixmap m_pixmap;
- bool m_translucentBackground;
-};
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qcolormap_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qcolormap_x11.cpp
deleted file mode 100644
index fddd3e03989..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qcolormap_x11.cpp
+++ /dev/null
@@ -1,615 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#include <QVarLengthArray>
-
-#include <private/qguiapplication_p.h>
-
-#include "qcolormap_x11_p.h"
-#include "qxcbnativepainting.h"
-#include "qt_x11_p.h"
-
-QT_BEGIN_NAMESPACE
-
-class QXcbColormapPrivate
-{
-public:
- QXcbColormapPrivate()
- : ref(1), mode(QXcbColormap::Direct), depth(0),
- colormap(0), defaultColormap(true),
- visual(0), defaultVisual(true),
- r_max(0), g_max(0), b_max(0),
- r_shift(0), g_shift(0), b_shift(0)
- {}
-
- QAtomicInt ref;
-
- QXcbColormap::Mode mode;
- int depth;
-
- Colormap colormap;
- bool defaultColormap;
-
- Visual *visual;
- bool defaultVisual;
-
- int r_max;
- int g_max;
- int b_max;
-
- uint r_shift;
- uint g_shift;
- uint b_shift;
-
- QList<QColor> colors;
- QList<int> pixels;
-};
-
-static uint right_align(uint v)
-{
- while (!(v & 0x1))
- v >>= 1;
- return v;
-}
-
-static int cube_root(int v)
-{
- if (v == 1)
- return 1;
- // brute force algorithm
- int i = 1;
- for (;;) {
- const int b = i * i * i;
- if (b <= v) {
- ++i;
- } else {
- --i;
- break;
- }
- }
- return i;
-}
-
-static Visual *find_visual(Display *display,
- int screen,
- int visual_class,
- int visual_id,
- int *depth,
- bool *defaultVisual)
-{
- XVisualInfo *vi, rvi;
- int count;
-
- uint mask = VisualScreenMask;
- rvi.screen = screen;
-
- if (visual_class != -1) {
- rvi.c_class = visual_class;
- mask |= VisualClassMask;
- }
- if (visual_id != -1) {
- rvi.visualid = visual_id;
- mask |= VisualIDMask;
- }
-
- Visual *visual = DefaultVisual(display, screen);
- *defaultVisual = true;
- *depth = DefaultDepth(display, screen);
-
- vi = XGetVisualInfo(display, mask, &rvi, &count);
- if (vi) {
- int best = 0;
- for (int x = 0; x < count; ++x) {
- if (vi[x].depth > vi[best].depth)
- best = x;
- }
- if (best >= 0 && best <= count && vi[best].visualid != XVisualIDFromVisual(visual)) {
- visual = vi[best].visual;
- *defaultVisual = (visual == DefaultVisual(display, screen));
- *depth = vi[best].depth;
- }
- }
- if (vi)
- XFree((char *)vi);
- return visual;
-}
-
-static void query_colormap(QXcbColormapPrivate *d, int screen)
-{
- Display *display = X11->display;
-
- // query existing colormap
- int q_colors = (((1u << d->depth) > 256u) ? 256u : (1u << d->depth));
- XColor queried[256];
- memset(queried, 0, sizeof(queried));
- for (int x = 0; x < q_colors; ++x)
- queried[x].pixel = x;
- XQueryColors(display, d->colormap, queried, q_colors);
-
- d->colors.resize(q_colors);
- for (int x = 0; x < q_colors; ++x) {
- if (queried[x].red == 0
- && queried[x].green == 0
- && queried[x].blue == 0
- && queried[x].pixel != BlackPixel(display, screen)) {
- // unallocated color cell, skip it
- continue;
- }
-
- d->colors[x] = QColor::fromRgbF(queried[x].red / float(USHRT_MAX),
- queried[x].green / float(USHRT_MAX),
- queried[x].blue / float(USHRT_MAX));
- }
-
- // for missing colors, find the closest color in the existing colormap
- Q_ASSERT(d->pixels.size());
- for (int x = 0; x < d->pixels.size(); ++x) {
- if (d->pixels.at(x) != -1)
- continue;
-
- QRgb rgb;
- if (d->mode == QXcbColormap::Indexed) {
- const int r = (x / (d->g_max * d->b_max)) % d->r_max;
- const int g = (x / d->b_max) % d->g_max;
- const int b = x % d->b_max;
- rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1),
- (g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1),
- (b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1));
- } else {
- rgb = qRgb(x, x, x);
- }
-
- // find closest color
- int mindist = INT_MAX, best = -1;
- for (int y = 0; y < q_colors; ++y) {
- int r = qRed(rgb) - (queried[y].red >> 8);
- int g = qGreen(rgb) - (queried[y].green >> 8);
- int b = qBlue(rgb) - (queried[y].blue >> 8);
- int dist = (r * r) + (g * g) + (b * b);
- if (dist < mindist) {
- mindist = dist;
- best = y;
- }
- }
-
- Q_ASSERT(best >= 0 && best < q_colors);
- if (d->visual->c_class & 1) {
- XColor xcolor;
- xcolor.red = queried[best].red;
- xcolor.green = queried[best].green;
- xcolor.blue = queried[best].blue;
- xcolor.pixel = queried[best].pixel;
-
- if (XAllocColor(display, d->colormap, &xcolor)) {
- d->pixels[x] = xcolor.pixel;
- } else {
- // some weird stuff is going on...
- d->pixels[x] = (qGray(rgb) < 127
- ? BlackPixel(display, screen)
- : WhitePixel(display, screen));
- }
- } else {
- d->pixels[x] = best;
- }
- }
-}
-
-static void init_gray(QXcbColormapPrivate *d, int screen)
-{
- d->pixels.resize(d->r_max);
-
- for (int g = 0; g < d->g_max; ++g) {
- const int gray = (g * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1);
- const QRgb rgb = qRgb(gray, gray, gray);
-
- d->pixels[g] = -1;
-
- if (d->visual->c_class & 1) {
- XColor xcolor;
- xcolor.red = qRed(rgb) * 0x101;
- xcolor.green = qGreen(rgb) * 0x101;
- xcolor.blue = qBlue(rgb) * 0x101;
- xcolor.pixel = 0ul;
-
- if (XAllocColor(X11->display, d->colormap, &xcolor))
- d->pixels[g] = xcolor.pixel;
- }
- }
-
- query_colormap(d, screen);
-}
-
-static void init_indexed(QXcbColormapPrivate *d, int screen)
-{
- d->pixels.resize(d->r_max * d->g_max * d->b_max);
-
- // create color cube
- for (int x = 0, r = 0; r < d->r_max; ++r) {
- for (int g = 0; g < d->g_max; ++g) {
- for (int b = 0; b < d->b_max; ++b, ++x) {
- const QRgb rgb = qRgb((r * 0xff + (d->r_max - 1) / 2) / (d->r_max - 1),
- (g * 0xff + (d->g_max - 1) / 2) / (d->g_max - 1),
- (b * 0xff + (d->b_max - 1) / 2) / (d->b_max - 1));
-
- d->pixels[x] = -1;
-
- if (d->visual->c_class & 1) {
- XColor xcolor;
- xcolor.red = qRed(rgb) * 0x101;
- xcolor.green = qGreen(rgb) * 0x101;
- xcolor.blue = qBlue(rgb) * 0x101;
- xcolor.pixel = 0ul;
-
- if (XAllocColor(X11->display, d->colormap, &xcolor))
- d->pixels[x] = xcolor.pixel;
- }
- }
- }
- }
-
- query_colormap(d, screen);
-}
-
-static void init_direct(QXcbColormapPrivate *d, bool ownColormap)
-{
- if (d->visual->c_class != DirectColor || !ownColormap)
- return;
-
- // preallocate 768 on the stack, so that we don't have to malloc
- // for the common case (<= 24 bpp)
- QVarLengthArray<XColor, 768> colorTable(d->r_max + d->g_max + d->b_max);
- int i = 0;
-
- for (int r = 0; r < d->r_max; ++r) {
- colorTable[i].red = r << 8 | r;
- colorTable[i].pixel = r << d->r_shift;
- colorTable[i].flags = DoRed;
- ++i;
- }
-
- for (int g = 0; g < d->g_max; ++g) {
- colorTable[i].green = g << 8 | g;
- colorTable[i].pixel = g << d->g_shift;
- colorTable[i].flags = DoGreen;
- ++i;
- }
-
- for (int b = 0; b < d->b_max; ++b) {
- colorTable[i].blue = (b << 8 | b);
- colorTable[i].pixel = b << d->b_shift;
- colorTable[i].flags = DoBlue;
- ++i;
- }
-
- XStoreColors(X11->display, d->colormap, colorTable.data(), colorTable.count());
-}
-
-static QXcbColormap **cmaps = nullptr;
-
-void QXcbColormap::initialize()
-{
- Display *display = X11->display;
- const int screens = ScreenCount(display);
-
- cmaps = new QXcbColormap*[screens];
-
- for (int i = 0; i < screens; ++i) {
- cmaps[i] = new QXcbColormap;
- QXcbColormapPrivate * const d = cmaps[i]->d;
-
- bool use_stdcmap = false;
- int color_count = X11->color_count;
-
- // defaults
- d->depth = DefaultDepth(display, i);
- d->colormap = DefaultColormap(display, i);
- d->defaultColormap = true;
- d->visual = DefaultVisual(display, i);
- d->defaultVisual = true;
-
- Visual *argbVisual = nullptr;
-
- if (X11->visual && i == DefaultScreen(display)) {
- // only use the outside colormap on the default screen
- d->visual = find_visual(display, i, X11->visual->c_class,
- XVisualIDFromVisual(X11->visual),
- &d->depth, &d->defaultVisual);
- } else if ((X11->visual_class != -1 && X11->visual_class >= 0 && X11->visual_class < 6)
- || (X11->visual_id != -1)) {
- // look for a specific visual or type of visual
- d->visual = find_visual(display, i, X11->visual_class, X11->visual_id,
- &d->depth, &d->defaultVisual);
- } else if (!X11->custom_cmap) {
- XStandardColormap *stdcmap = nullptr;
- int ncmaps = 0;
-
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- int nvi;
- XVisualInfo templ;
- templ.screen = i;
- templ.depth = 32;
- templ.c_class = TrueColor;
- XVisualInfo *xvi = XGetVisualInfo(X11->display, VisualScreenMask |
- VisualDepthMask |
- VisualClassMask, &templ, &nvi);
- for (int idx = 0; idx < nvi; ++idx) {
- XRenderPictFormat *format = XRenderFindVisualFormat(X11->display,
- xvi[idx].visual);
- if (format->type == PictTypeDirect && format->direct.alphaMask) {
- argbVisual = xvi[idx].visual;
- break;
- }
- }
- XFree(xvi);
- }
-#endif
- if (XGetRGBColormaps(display, RootWindow(display, i),
- &stdcmap, &ncmaps, XA_RGB_DEFAULT_MAP)) {
- if (stdcmap) {
- for (int c = 0; c < ncmaps; ++c) {
- if (!stdcmap[c].red_max ||
- !stdcmap[c].green_max ||
- !stdcmap[c].blue_max ||
- !stdcmap[c].red_mult ||
- !stdcmap[c].green_mult ||
- !stdcmap[c].blue_mult)
- continue; // invalid stdcmap
-
- XVisualInfo proto;
- proto.visualid = stdcmap[c].visualid;
- proto.screen = i;
-
- int nvisuals = 0;
- XVisualInfo *vi = XGetVisualInfo(display, VisualIDMask | VisualScreenMask,
- &proto, &nvisuals);
- if (vi) {
- if (nvisuals > 0) {
- use_stdcmap = true;
-
- d->mode = ((vi[0].visual->c_class < StaticColor)
- ? Gray
- : ((vi[0].visual->c_class < TrueColor)
- ? Indexed
- : Direct));
-
- d->depth = vi[0].depth;
- d->colormap = stdcmap[c].colormap;
- d->defaultColormap = true;
- d->visual = vi[0].visual;
- d->defaultVisual = (d->visual == DefaultVisual(display, i));
-
- d->r_max = stdcmap[c].red_max + 1;
- d->g_max = stdcmap[c].green_max + 1;
- d->b_max = stdcmap[c].blue_max + 1;
-
- if (d->mode == Direct) {
- // calculate offsets
- d->r_shift = lowest_bit(d->visual->red_mask);
- d->g_shift = lowest_bit(d->visual->green_mask);
- d->b_shift = lowest_bit(d->visual->blue_mask);
- } else {
- d->r_shift = 0;
- d->g_shift = 0;
- d->b_shift = 0;
- }
- }
- XFree(vi);
- }
- break;
- }
- XFree(stdcmap);
- }
- }
- }
- if (!use_stdcmap) {
- switch (d->visual->c_class) {
- case StaticGray:
- d->mode = Gray;
-
- d->r_max = d->g_max = d->b_max = d->visual->map_entries;
- break;
-
- case XGrayScale:
- d->mode = Gray;
-
- // follow precedent set in libXmu...
- if (color_count != 0)
- d->r_max = d->g_max = d->b_max = color_count;
- else if (d->visual->map_entries > 65000)
- d->r_max = d->g_max = d->b_max = 4096;
- else if (d->visual->map_entries > 4000)
- d->r_max = d->g_max = d->b_max = 512;
- else if (d->visual->map_entries > 250)
- d->r_max = d->g_max = d->b_max = 12;
- else
- d->r_max = d->g_max = d->b_max = 4;
- break;
-
- case StaticColor:
- d->mode = Indexed;
-
- d->r_max = right_align(d->visual->red_mask) + 1;
- d->g_max = right_align(d->visual->green_mask) + 1;
- d->b_max = right_align(d->visual->blue_mask) + 1;
- break;
-
- case PseudoColor:
- d->mode = Indexed;
-
- // follow precedent set in libXmu...
- if (color_count != 0)
- d->r_max = d->g_max = d->b_max = cube_root(color_count);
- else if (d->visual->map_entries > 65000)
- d->r_max = d->g_max = d->b_max = 27;
- else if (d->visual->map_entries > 4000)
- d->r_max = d->g_max = d->b_max = 12;
- else if (d->visual->map_entries > 250)
- d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries - 125);
- else
- d->r_max = d->g_max = d->b_max = cube_root(d->visual->map_entries);
- break;
-
- case TrueColor:
- case DirectColor:
- d->mode = Direct;
-
- d->r_max = right_align(d->visual->red_mask) + 1;
- d->g_max = right_align(d->visual->green_mask) + 1;
- d->b_max = right_align(d->visual->blue_mask) + 1;
-
- d->r_shift = lowest_bit(d->visual->red_mask);
- d->g_shift = lowest_bit(d->visual->green_mask);
- d->b_shift = lowest_bit(d->visual->blue_mask);
- break;
- }
- }
-
- bool ownColormap = false;
- if (X11->colormap && i == DefaultScreen(display)) {
- // only use the outside colormap on the default screen
- d->colormap = X11->colormap;
- d->defaultColormap = (d->colormap == DefaultColormap(display, i));
- } else if ((!use_stdcmap
- && (((d->visual->c_class & 1) && X11->custom_cmap)
- || d->visual != DefaultVisual(display, i)))
- || d->visual->c_class == DirectColor) {
- // allocate custom colormap (we always do this when using DirectColor visuals)
- d->colormap =
- XCreateColormap(display, RootWindow(display, i), d->visual,
- d->visual->c_class == DirectColor ? AllocAll : AllocNone);
- d->defaultColormap = false;
- ownColormap = true;
- }
-
- switch (d->mode) {
- case Gray:
- init_gray(d, i);
- break;
- case Indexed:
- init_indexed(d, i);
- break;
- case Direct:
- init_direct(d, ownColormap);
- break;
- }
-
- QX11InfoData *screen = X11->screens + i;
- screen->depth = d->depth;
- screen->visual = d->visual;
- screen->defaultVisual = d->defaultVisual;
- screen->colormap = d->colormap;
- screen->defaultColormap = d->defaultColormap;
- screen->cells = screen->visual->map_entries;
-
- if (argbVisual) {
- X11->argbVisuals[i] = argbVisual;
- X11->argbColormaps[i] = XCreateColormap(display, RootWindow(display, i), argbVisual, AllocNone);
- }
-
- // ###
- // We assume that 8bpp == pseudocolor, but this is not
- // always the case (according to the X server), so we need
- // to make sure that our internal data is setup in a way
- // that is compatible with our assumptions
- if (screen->visual->c_class == TrueColor && screen->depth == 8 && screen->cells == 8)
- screen->cells = 256;
- }
-}
-
-void QXcbColormap::cleanup()
-{
- Display *display = X11->display;
- const int screens = ScreenCount(display);
-
- for (int i = 0; i < screens; ++i)
- delete cmaps[i];
-
- delete [] cmaps;
- cmaps = 0;
-}
-
-
-QXcbColormap QXcbColormap::instance(int screen)
-{
- if (screen == -1)
- screen = QXcbX11Info::appScreen();
- return *cmaps[screen];
-}
-
-/*! \internal
- Constructs a new colormap.
-*/
-QXcbColormap::QXcbColormap()
- : d(new QXcbColormapPrivate)
-{}
-
-QXcbColormap::QXcbColormap(const QXcbColormap &colormap)
- :d (colormap.d)
-{ d->ref.ref(); }
-
-QXcbColormap::~QXcbColormap()
-{
- if (!d->ref.deref()) {
- if (!d->defaultColormap)
- XFreeColormap(X11->display, d->colormap);
- delete d;
- }
-}
-
-QXcbColormap::Mode QXcbColormap::mode() const
-{ return d->mode; }
-
-int QXcbColormap::depth() const
-{ return d->depth; }
-
-int QXcbColormap::size() const
-{
- return (d->mode == Gray
- ? d->r_max
- : (d->mode == Indexed
- ? d->r_max * d->g_max * d->b_max
- : -1));
-}
-
-uint QXcbColormap::pixel(const QColor &color) const
-{
- const QRgba64 rgba64 = color.rgba64();
- // XXX We emulate the raster engine here by getting the
- // 8-bit values, but we could instead use the 16-bit
- // values for slightly better color accuracy
- const uint r = (rgba64.red8() * d->r_max) >> 8;
- const uint g = (rgba64.green8() * d->g_max) >> 8;
- const uint b = (rgba64.blue8() * d->b_max) >> 8;
- if (d->mode != Direct) {
- if (d->mode == Gray)
- return d->pixels.at((r * 30 + g * 59 + b * 11) / 100);
- return d->pixels.at(r * d->g_max * d->b_max + g * d->b_max + b);
- }
- return (r << d->r_shift) + (g << d->g_shift) + (b << d->b_shift);
-}
-
-const QColor QXcbColormap::colorAt(uint pixel) const
-{
- if (d->mode != Direct) {
- Q_ASSERT(pixel <= (uint)d->colors.size());
- return d->colors.at(pixel);
- }
-
- const int r = (((pixel & d->visual->red_mask) >> d->r_shift) << 8) / d->r_max;
- const int g = (((pixel & d->visual->green_mask) >> d->g_shift) << 8) / d->g_max;
- const int b = (((pixel & d->visual->blue_mask) >> d->b_shift) << 8) / d->b_max;
- return QColor(r, g, b);
-}
-
-const QList<QColor> QXcbColormap::colormap() const
-{ return d->colors; }
-
-QXcbColormap &QXcbColormap::operator=(const QXcbColormap &colormap)
-{
- qAtomicAssign(d, colormap.d);
- return *this;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qcolormap_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qcolormap_x11_p.h
deleted file mode 100644
index 9c9cce424c9..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qcolormap_x11_p.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-#include <QColor>
-#include <QList>
-
-QT_BEGIN_NAMESPACE
-
-class QXcbColormapPrivate;
-class QXcbColormap
-{
-public:
- enum Mode { Direct, Indexed, Gray };
-
- static void initialize();
- static void cleanup();
-
- static QXcbColormap instance(int screen = -1);
-
- QXcbColormap(const QXcbColormap &colormap);
- ~QXcbColormap();
-
- QXcbColormap &operator=(const QXcbColormap &colormap);
-
- Mode mode() const;
-
- int depth() const;
- int size() const;
-
- uint pixel(const QColor &color) const;
- const QColor colorAt(uint pixel) const;
-
- const QList<QColor> colormap() const;
-
-private:
- QXcbColormap();
- QXcbColormapPrivate *d;
-};
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
deleted file mode 100644
index 2f3827025f3..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11.cpp
+++ /dev/null
@@ -1,2807 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#include <QtCore/qrandom.h>
-
-#include <private/qpixmapcache_p.h>
-#include <private/qpaintengine_p.h>
-#include <private/qpainterpath_p.h>
-#include <private/qdrawhelper_p.h>
-#include <private/qfontengineglyphcache_p.h>
-
-#if QT_CONFIG(fontconfig)
-#include <private/qfontengine_ft_p.h>
-#endif
-
-#include "qpaintengine_x11_p.h"
-#include "qpolygonclipper_p.h"
-#include "qtessellator_p.h"
-#include "qpixmap_x11_p.h"
-#include "qcolormap_x11_p.h"
-#include "qt_x11_p.h"
-#include "qxcbexport.h"
-#include "qxcbnativepainting.h"
-
-QT_BEGIN_NAMESPACE
-
-using namespace Qt::StringLiterals;
-
-#if QT_CONFIG(xrender)
-
-class QXRenderTessellator : public QTessellator
-{
-public:
- QXRenderTessellator() : traps(0), allocated(0), size(0) {}
- ~QXRenderTessellator() { free(traps); }
- XTrapezoid *traps;
- int allocated;
- int size;
- void addTrap(const Trapezoid &trap) override;
- QRect tessellate(const QPointF *points, int nPoints, bool winding) {
- size = 0;
- setWinding(winding);
- return QTessellator::tessellate(points, nPoints).toRect();
- }
- void done() {
- if (allocated > 64) {
- free(traps);
- traps = 0;
- allocated = 0;
- }
- }
-};
-
-void QXRenderTessellator::addTrap(const Trapezoid &trap)
-{
- if (size == allocated) {
- allocated = qMax(2*allocated, 64);
- traps = q_check_ptr((XTrapezoid *)realloc(traps, allocated * sizeof(XTrapezoid)));
- }
- traps[size].top = Q27Dot5ToXFixed(trap.top);
- traps[size].bottom = Q27Dot5ToXFixed(trap.bottom);
- traps[size].left.p1.x = Q27Dot5ToXFixed(trap.topLeft->x);
- traps[size].left.p1.y = Q27Dot5ToXFixed(trap.topLeft->y);
- traps[size].left.p2.x = Q27Dot5ToXFixed(trap.bottomLeft->x);
- traps[size].left.p2.y = Q27Dot5ToXFixed(trap.bottomLeft->y);
- traps[size].right.p1.x = Q27Dot5ToXFixed(trap.topRight->x);
- traps[size].right.p1.y = Q27Dot5ToXFixed(trap.topRight->y);
- traps[size].right.p2.x = Q27Dot5ToXFixed(trap.bottomRight->x);
- traps[size].right.p2.y = Q27Dot5ToXFixed(trap.bottomRight->y);
- ++size;
-}
-
-#endif // QT_CONFIG(xrender)
-
-class QX11PaintEnginePrivate : public QPaintEnginePrivate
-{
- Q_DECLARE_PUBLIC(QX11PaintEngine)
-public:
- QX11PaintEnginePrivate()
- {
- opacity = 1.0;
- scrn = -1;
- hd = 0;
- picture = 0;
- gc = gc_brush = 0;
- dpy = 0;
- xinfo = 0;
- txop = QTransform::TxNone;
- has_clipping = false;
- render_hints = 0;
- xform_scale = 1;
-#if QT_CONFIG(xrender)
- tessellator = 0;
-#endif
- }
- enum GCMode {
- PenGC,
- BrushGC
- };
-
- void init();
- void fillPolygon_translated(const QPointF *points, int pointCount, GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode);
- void fillPolygon_dev(const QPointF *points, int pointCount, GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode);
- void fillPath(const QPainterPath &path, GCMode gcmode, bool transform);
- void strokePolygon_dev(const QPointF *points, int pointCount, bool close);
- void strokePolygon_translated(const QPointF *points, int pointCount, bool close);
- void setupAdaptedOrigin(const QPoint &p);
- void resetAdaptedOrigin();
- void decidePathFallback() {
- use_path_fallback = has_alpha_brush
- || has_alpha_pen
- || has_custom_pen
- || has_complex_xform
- || (render_hints & QPainter::Antialiasing);
- }
- void decideCoordAdjust() {
- adjust_coords = false;
- }
- void clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly);
- void systemStateChanged() override;
- inline bool isCosmeticPen() const {
- return cpen.isCosmetic();
- }
-
- Display *dpy;
- int scrn;
- int pdev_depth;
- unsigned long hd;
- QPixmap brush_pm;
-#if QT_CONFIG(xrender)
- unsigned long picture;
- unsigned long current_brush;
- QPixmap bitmap_texture;
- int composition_mode;
-#else
- unsigned long picture;
-#endif
- GC gc;
- GC gc_brush;
-
- QPen cpen;
- QBrush cbrush;
- QRegion crgn;
- QTransform matrix;
- qreal opacity;
-
- uint has_complex_xform : 1;
- uint has_scaling_xform : 1;
- uint has_non_scaling_xform : 1;
- uint has_custom_pen : 1;
- uint use_path_fallback : 1;
- uint adjust_coords : 1;
- uint has_clipping : 1;
- uint adapted_brush_origin : 1;
- uint adapted_pen_origin : 1;
- uint has_pen : 1;
- uint has_brush : 1;
- uint has_texture : 1;
- uint has_alpha_texture : 1;
- uint has_pattern : 1;
- uint has_alpha_pen : 1;
- uint has_alpha_brush : 1;
- uint use_sysclip : 1;
- uint render_hints;
-
- const QXcbX11Info *xinfo;
- QPointF bg_origin;
- QTransform::TransformationType txop;
- qreal xform_scale;
-
- struct qt_float_point
- {
- qreal x, y;
- };
- QPolygonClipper<qt_float_point, qt_float_point, float> polygonClipper;
-
- int xlibMaxLinePoints;
-#if QT_CONFIG(xrender)
- QXRenderTessellator *tessellator;
-#endif
-};
-
-#if QT_CONFIG(xrender)
-class QXRenderGlyphCache : public QFontEngineGlyphCache
-{
-public:
- QXRenderGlyphCache(QXcbX11Info x, QFontEngine::GlyphFormat format, const QTransform &matrix);
- ~QXRenderGlyphCache();
-
- bool addGlyphs(const QTextItemInt &ti,
- const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions);
- bool draw(Drawable src, Drawable dst, const QTransform &matrix, const QTextItemInt &ti);
-
- inline GlyphSet glyphSet();
- inline int glyphBufferSize(const QFontEngineFT::Glyph &glyph) const;
-
- inline QImage::Format imageFormat() const;
- inline const XRenderPictFormat *renderPictFormat() const;
-
- static inline QFontEngine::GlyphFormat glyphFormatForDepth(QFontEngine *fontEngine, int depth);
- static inline Glyph glyphId(glyph_t glyph, QFixed subPixelPosition);
-
- static inline bool isValidCoordinate(const QFixedPoint &fp);
-
-private:
- QXcbX11Info xinfo;
- GlyphSet gset;
- QSet<Glyph> cachedGlyphs;
-};
-#endif // QT_CONFIG(xrender)
-
-extern QPixmap qt_pixmapForBrush(int brushStyle, bool invert); //in qbrush.cpp
-extern QPixmap qt_toX11Pixmap(const QPixmap &pixmap);
-
-extern "C" {
-Q_XCB_EXPORT Drawable qt_x11Handle(const QPaintDevice *pd)
-{
- if (!pd)
- return 0;
-
-// if (pd->devType() == QInternal::Widget)
-// return static_cast<const QWidget *>(pd)->handle();
-
- if (pd->devType() == QInternal::Pixmap)
- return qt_x11PixmapHandle(*static_cast<const QPixmap *>(pd));
-
- return 0;
-}
-}
-
-static const QXcbX11Info *qt_x11Info(const QPaintDevice *pd)
-{
- if (!pd)
- return 0;
-
-// if (pd->devType() == QInternal::Widget)
-// return &static_cast<const QWidget *>(pd)->x11Info();
-
- if (pd->devType() == QInternal::Pixmap)
- return &qt_x11Info(*static_cast<const QPixmap *>(pd));
-
- return 0;
-}
-
-// use the same rounding as in qrasterizer.cpp (6 bit fixed point)
-static const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-
-#undef X11 // defined in qt_x11_p.h
-extern "C" {
-/*!
- Returns the X11 specific pen GC for the painter \a p. Note that
- QPainter::begin() must be called before this function returns a
- valid GC.
-*/
-GC Q_XCB_EXPORT qt_x11_get_pen_gc(QPainter *p)
-{
- if (p && p->paintEngine()
- && p->paintEngine()->isActive()
- && p->paintEngine()->type() == QPaintEngine::X11) {
- return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc;
- }
- return 0;
-}
-
-/*!
- Returns the X11 specific brush GC for the painter \a p. Note that
- QPainter::begin() must be called before this function returns a
- valid GC.
-*/
-GC Q_XCB_EXPORT qt_x11_get_brush_gc(QPainter *p)
-{
- if (p && p->paintEngine()
- && p->paintEngine()->isActive()
- && p->paintEngine()->type() == QPaintEngine::X11) {
- return static_cast<QX11PaintEngine *>(p->paintEngine())->d_func()->gc_brush;
- }
- return 0;
-}
-}
-#define X11 qt_x11Data
-
-// internal helper. Converts an integer value to an unique string token
-template <typename T>
- struct HexString
-{
- inline HexString(const T t)
- : val(t)
- {}
-
- inline void write(QChar *&dest) const
- {
- const ushort hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
- const char *c = reinterpret_cast<const char *>(&val);
- for (uint i = 0; i < sizeof(T); ++i) {
- *dest++ = hexChars[*c & 0xf];
- *dest++ = hexChars[(*c & 0xf0) >> 4];
- ++c;
- }
- }
- const T val;
-};
-
-// specialization to enable fast concatenating of our string tokens to a string
-template <typename T>
- struct QConcatenable<HexString<T> >
-{
- typedef HexString<T> type;
- enum { ExactSize = true };
- static int size(const HexString<T> &) { return sizeof(T) * 2; }
- static inline void appendTo(const HexString<T> &str, QChar *&out) { str.write(out); }
- typedef QString ConvertTo;
-};
-
-#if QT_CONFIG(xrender)
-static const int compositionModeToRenderOp[QPainter::CompositionMode_Xor + 1] = {
- PictOpOver, //CompositionMode_SourceOver,
- PictOpOverReverse, //CompositionMode_DestinationOver,
- PictOpClear, //CompositionMode_Clear,
- PictOpSrc, //CompositionMode_Source,
- PictOpDst, //CompositionMode_Destination,
- PictOpIn, //CompositionMode_SourceIn,
- PictOpInReverse, //CompositionMode_DestinationIn,
- PictOpOut, //CompositionMode_SourceOut,
- PictOpOutReverse, //CompositionMode_DestinationOut,
- PictOpAtop, //CompositionMode_SourceAtop,
- PictOpAtopReverse, //CompositionMode_DestinationAtop,
- PictOpXor //CompositionMode_Xor
-};
-
-static inline int qpainterOpToXrender(QPainter::CompositionMode mode)
-{
- Q_ASSERT(mode <= QPainter::CompositionMode_Xor);
- return compositionModeToRenderOp[mode];
-}
-
-static inline bool complexPictOp(int op)
-{
- return op != PictOpOver && op != PictOpSrc;
-}
-#endif
-
-static inline void x11SetClipRegion(Display *dpy, GC gc, GC gc2,
-#if QT_CONFIG(xrender)
- Picture picture,
-#else
- Qt::HANDLE picture,
-#endif
- const QRegion &r)
-{
-// int num;
-// XRectangle *rects = (XRectangle *)qt_getClipRects(r, num);
- QList<XRectangle> rects = qt_region_to_xrectangles(r);
- int num = rects.size();
-
- if (gc)
- XSetClipRectangles( dpy, gc, 0, 0, rects.data(), num, Unsorted );
- if (gc2)
- XSetClipRectangles( dpy, gc2, 0, 0, rects.data(), num, Unsorted );
-
-#if QT_CONFIG(xrender)
- if (picture)
- XRenderSetPictureClipRectangles(dpy, picture, 0, 0, rects.data(), num);
-#else
- Q_UNUSED(picture);
-#endif // QT_CONFIG(xrender)
-}
-
-
-static inline void x11ClearClipRegion(Display *dpy, GC gc, GC gc2,
-#if QT_CONFIG(xrender)
- Picture picture
-#else
- Qt::HANDLE picture
-#endif
- )
-{
- if (gc)
- XSetClipMask(dpy, gc, XNone);
- if (gc2)
- XSetClipMask(dpy, gc2, XNone);
-
-#if QT_CONFIG(xrender)
- if (picture) {
- XRenderPictureAttributes attrs;
- attrs.clip_mask = XNone;
- XRenderChangePicture (dpy, picture, CPClipMask, &attrs);
- }
-#else
- Q_UNUSED(picture);
-#endif // QT_CONFIG(xrender)
-}
-
-
-#define DITHER_SIZE 16
-static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = {
- { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
- { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
- { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
- { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
- { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
- { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
- { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
- { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
- { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
- { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
- { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
- { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
- { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
- { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
- { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
- { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
-};
-
-static QPixmap qt_patternForAlpha(uchar alpha, int screen)
-{
- QPixmap pm;
- QString key = "$qt-alpha-brush$"_L1
- % HexString<uchar>(alpha)
- % HexString<int>(screen);
-
- if (!QPixmapCache::find(key, &pm)) {
- // #### why not use a mono image here????
- QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32);
- pattern.fill(0xffffffff);
- for (int y = 0; y < DITHER_SIZE; ++y) {
- for (int x = 0; x < DITHER_SIZE; ++x) {
- if (base_dither_matrix[x][y] <= alpha)
- pattern.setPixel(x, y, 0x00000000);
- }
- }
- pm = QBitmap::fromImage(pattern);
- qt_x11SetScreen(pm, screen);
- //pm.x11SetScreen(screen);
- QPixmapCache::insert(key, pm);
- }
- return pm;
-}
-
-
-#if QT_CONFIG(xrender)
-static Picture getPatternFill(int screen, const QBrush &b)
-{
- if (!X11->use_xrender)
- return XNone;
-
- XRenderColor color = X11->preMultiply(b.color());
- XRenderColor bg_color;
-
- bg_color = X11->preMultiply(QColor(0, 0, 0, 0));
-
- for (int i = 0; i < X11->pattern_fill_count; ++i) {
- if (X11->pattern_fills[i].screen == screen
- && X11->pattern_fills[i].opaque == false
- && X11->pattern_fills[i].style == b.style()
- && X11->pattern_fills[i].color.alpha == color.alpha
- && X11->pattern_fills[i].color.red == color.red
- && X11->pattern_fills[i].color.green == color.green
- && X11->pattern_fills[i].color.blue == color.blue
- && X11->pattern_fills[i].bg_color.alpha == bg_color.alpha
- && X11->pattern_fills[i].bg_color.red == bg_color.red
- && X11->pattern_fills[i].bg_color.green == bg_color.green
- && X11->pattern_fills[i].bg_color.blue == bg_color.blue)
- return X11->pattern_fills[i].picture;
- }
- // none found, replace one
- int i = QRandomGenerator::global()->generate() % 16;
-
- if (X11->pattern_fills[i].screen != screen && X11->pattern_fills[i].picture) {
- XRenderFreePicture (QXcbX11Info::display(), X11->pattern_fills[i].picture);
- X11->pattern_fills[i].picture = 0;
- }
-
- if (!X11->pattern_fills[i].picture) {
- Pixmap pixmap = XCreatePixmap (QXcbX11Info::display(), RootWindow (QXcbX11Info::display(), screen), 8, 8, 32);
- XRenderPictureAttributes attrs;
- attrs.repeat = True;
- X11->pattern_fills[i].picture = XRenderCreatePicture (QXcbX11Info::display(), pixmap,
- XRenderFindStandardFormat(QXcbX11Info::display(), PictStandardARGB32),
- CPRepeat, &attrs);
- XFreePixmap (QXcbX11Info::display(), pixmap);
- }
-
- X11->pattern_fills[i].screen = screen;
- X11->pattern_fills[i].color = color;
- X11->pattern_fills[i].bg_color = bg_color;
- X11->pattern_fills[i].opaque = false;
- X11->pattern_fills[i].style = b.style();
-
- XRenderFillRectangle(QXcbX11Info::display(), PictOpSrc, X11->pattern_fills[i].picture, &bg_color, 0, 0, 8, 8);
-
- QPixmap pattern(qt_pixmapForBrush(b.style(), true));
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(QXcbX11Info::display(), qt_x11PictureHandle(pattern), CPRepeat, &attrs);
-
- Picture fill_fg = X11->getSolidFill(screen, b.color());
- XRenderComposite(QXcbX11Info::display(), PictOpOver, fill_fg, qt_x11PictureHandle(pattern),
- X11->pattern_fills[i].picture,
- 0, 0, 0, 0, 0, 0, 8, 8);
-
- return X11->pattern_fills[i].picture;
-}
-
-static void qt_render_bitmap(Display *dpy, int scrn, Picture src, Picture dst,
- int sx, int sy, int x, int y, int sw, int sh,
- const QPen &pen)
-{
- Picture fill_fg = X11->getSolidFill(scrn, pen.color());
- XRenderComposite(dpy, PictOpOver,
- fill_fg, src, dst, sx, sy, sx, sy, x, y, sw, sh);
-}
-#endif
-
-void QX11PaintEnginePrivate::init()
-{
- dpy = 0;
- scrn = 0;
- hd = 0;
- picture = 0;
- xinfo = 0;
-#if QT_CONFIG(xrender)
- current_brush = 0;
- composition_mode = PictOpOver;
- tessellator = new QXRenderTessellator;
-#endif
-}
-
-void QX11PaintEnginePrivate::setupAdaptedOrigin(const QPoint &p)
-{
- if (adapted_pen_origin)
- XSetTSOrigin(dpy, gc, p.x(), p.y());
- if (adapted_brush_origin)
- XSetTSOrigin(dpy, gc_brush, p.x(), p.y());
-}
-
-void QX11PaintEnginePrivate::resetAdaptedOrigin()
-{
- if (adapted_pen_origin)
- XSetTSOrigin(dpy, gc, 0, 0);
- if (adapted_brush_origin)
- XSetTSOrigin(dpy, gc_brush, 0, 0);
-}
-
-void QX11PaintEnginePrivate::clipPolygon_dev(const QPolygonF &poly, QPolygonF *clipped_poly)
-{
- int clipped_count = 0;
- qt_float_point *clipped_points = 0;
- polygonClipper.clipPolygon((qt_float_point *) poly.data(), poly.size(),
- &clipped_points, &clipped_count);
- clipped_poly->resize(clipped_count);
- for (int i=0; i<clipped_count; ++i)
- (*clipped_poly)[i] = *((QPointF *)(&clipped_points[i]));
-}
-
-void QX11PaintEnginePrivate::systemStateChanged()
-{
- Q_Q(QX11PaintEngine);
- QPainter *painter = q->state ? q->state->painter() : nullptr;
- if (painter && painter->hasClipping()) {
- if (q->testDirty(QPaintEngine::DirtyTransform))
- q->updateMatrix(q->state->transform());
- QPolygonF clip_poly_dev(matrix.map(painter->clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- q->updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
- } else {
- q->updateClipRegion_dev(QRegion(), Qt::NoClip);
- }
-}
-
-static QPaintEngine::PaintEngineFeatures qt_decide_features()
-{
- QPaintEngine::PaintEngineFeatures features =
- QPaintEngine::PrimitiveTransform
- | QPaintEngine::PatternBrush
- | QPaintEngine::AlphaBlend
- | QPaintEngine::PainterPaths
- | QPaintEngine::RasterOpModes;
-
- if (X11->use_xrender) {
- features |= QPaintEngine::Antialiasing;
- features |= QPaintEngine::PorterDuff;
- features |= QPaintEngine::MaskedBrush;
-#if 0
- if (X11->xrender_version > 10) {
- features |= QPaintEngine::LinearGradientFill;
- // ###
- }
-#endif
- }
-
- return features;
-}
-
-/*
- * QX11PaintEngine members
- */
-
-QX11PaintEngine::QX11PaintEngine()
- : QPaintEngine(*(new QX11PaintEnginePrivate), qt_decide_features())
-{
- Q_D(QX11PaintEngine);
- d->init();
-}
-
-QX11PaintEngine::QX11PaintEngine(QX11PaintEnginePrivate &dptr)
- : QPaintEngine(dptr, qt_decide_features())
-{
- Q_D(QX11PaintEngine);
- d->init();
-}
-
-QX11PaintEngine::~QX11PaintEngine()
-{
-#if QT_CONFIG(xrender)
- Q_D(QX11PaintEngine);
- delete d->tessellator;
-#endif
-}
-
-bool QX11PaintEngine::begin(QPaintDevice *pdev)
-{
- Q_D(QX11PaintEngine);
- d->xinfo = qt_x11Info(pdev);
-#if QT_CONFIG(xrender)
- if (pdev->devType() == QInternal::Pixmap) {
- const QPixmap *pm = static_cast<const QPixmap *>(pdev);
- QX11PlatformPixmap *data = static_cast<QX11PlatformPixmap*>(pm->handle());
- if (X11->use_xrender && data->depth() != 32 && data->x11_mask)
- data->convertToARGB32();
- d->picture = qt_x11PictureHandle(*static_cast<const QPixmap *>(pdev));
- }
-#else
- d->picture = 0;
-#endif
- d->hd = qt_x11Handle(pdev);
-
- Q_ASSERT(d->xinfo != 0);
- d->dpy = d->xinfo->display(); // get display variable
- d->scrn = d->xinfo->screen(); // get screen variable
-
- d->crgn = QRegion();
- d->gc = XCreateGC(d->dpy, d->hd, 0, 0);
- d->gc_brush = XCreateGC(d->dpy, d->hd, 0, 0);
- d->has_alpha_brush = false;
- d->has_alpha_pen = false;
- d->has_clipping = false;
- d->has_complex_xform = false;
- d->has_scaling_xform = false;
- d->has_non_scaling_xform = true;
- d->xform_scale = 1;
- d->has_custom_pen = false;
- d->matrix = QTransform();
- d->pdev_depth = d->pdev->depth();
- d->render_hints = 0;
- d->txop = QTransform::TxNone;
- d->use_path_fallback = false;
-#if QT_CONFIG(xrender)
- d->composition_mode = PictOpOver;
-#endif
- d->xlibMaxLinePoints = 32762; // a safe number used to avoid, call to XMaxRequestSize(d->dpy) - 3;
- d->opacity = 1;
-
- QX11PlatformPixmap *x11pm = paintDevice()->devType() == QInternal::Pixmap ? qt_x11Pixmap(*static_cast<QPixmap *>(paintDevice())) : nullptr;
- d->use_sysclip = paintDevice()->devType() == QInternal::Widget || (x11pm ? x11pm->isBackingStore() : false);
-
- // Set up the polygon clipper. Note: This will only work in
- // polyline mode as long as we have a buffer zone, since a
- // polyline may be clipped into several non-connected polylines.
- const int BUFFERZONE = 1000;
- QRect devClipRect(-BUFFERZONE, -BUFFERZONE,
- pdev->width() + 2*BUFFERZONE, pdev->height() + 2*BUFFERZONE);
- d->polygonClipper.setBoundingRect(devClipRect);
-
- setSystemClip(systemClip());
- d->systemStateChanged();
-
- qt_x11SetDefaultScreen(d->xinfo->screen());
-
- updatePen(QPen(Qt::black));
- updateBrush(QBrush(Qt::white), QPoint());
-
- setDirty(QPaintEngine::DirtyClipRegion);
- setDirty(QPaintEngine::DirtyPen);
- setDirty(QPaintEngine::DirtyBrush);
- setDirty(QPaintEngine::DirtyBackground);
-
- setActive(true);
- return true;
-}
-
-bool QX11PaintEngine::end()
-{
- Q_D(QX11PaintEngine);
-
-#if QT_CONFIG(xrender)
- if (d->picture) {
- // reset clipping/subwindow mode on our render picture
- XRenderPictureAttributes attrs;
- attrs.subwindow_mode = ClipByChildren;
- attrs.clip_mask = XNone;
- XRenderChangePicture(d->dpy, d->picture, CPClipMask|CPSubwindowMode, &attrs);
- }
-#endif
-
- if (d->gc_brush && d->pdev->painters < 2) {
- XFreeGC(d->dpy, d->gc_brush);
- d->gc_brush = 0;
- }
-
- if (d->gc && d->pdev->painters < 2) {
- XFreeGC(d->dpy, d->gc);
- d->gc = 0;
- }
-
- // Restore system clip for alien widgets painting outside the paint event.
-// if (d->pdev->devType() == QInternal::Widget && !static_cast<QWidget *>(d->pdev)->internalWinId())
- d->currentClipDevice = nullptr;
- setSystemClip(QRegion());
-
- setActive(false);
- return true;
-}
-
-static bool clipLine(QLineF *line, const QRect &rect)
-{
- qreal x1 = line->x1();
- qreal x2 = line->x2();
- qreal y1 = line->y1();
- qreal y2 = line->y2();
-
- qreal left = rect.x();
- qreal right = rect.x() + rect.width() - 1;
- qreal top = rect.y();
- qreal bottom = rect.y() + rect.height() - 1;
-
- enum { Left, Right, Top, Bottom };
- // clip the lines, after cohen-sutherland, see e.g. http://www.nondot.org/~sabre/graphpro/line6.html
- int p1 = ((x1 < left) << Left)
- | ((x1 > right) << Right)
- | ((y1 < top) << Top)
- | ((y1 > bottom) << Bottom);
- int p2 = ((x2 < left) << Left)
- | ((x2 > right) << Right)
- | ((y2 < top) << Top)
- | ((y2 > bottom) << Bottom);
-
- if (p1 & p2)
- // completely outside
- return false;
-
- if (p1 | p2) {
- qreal dx = x2 - x1;
- qreal dy = y2 - y1;
-
- // clip x coordinates
- if (x1 < left) {
- y1 += dy/dx * (left - x1);
- x1 = left;
- } else if (x1 > right) {
- y1 -= dy/dx * (x1 - right);
- x1 = right;
- }
- if (x2 < left) {
- y2 += dy/dx * (left - x2);
- x2 = left;
- } else if (x2 > right) {
- y2 -= dy/dx * (x2 - right);
- x2 = right;
- }
- p1 = ((y1 < top) << Top)
- | ((y1 > bottom) << Bottom);
- p2 = ((y2 < top) << Top)
- | ((y2 > bottom) << Bottom);
- if (p1 & p2)
- return false;
- // clip y coordinates
- if (y1 < top) {
- x1 += dx/dy * (top - y1);
- y1 = top;
- } else if (y1 > bottom) {
- x1 -= dx/dy * (y1 - bottom);
- y1 = bottom;
- }
- if (y2 < top) {
- x2 += dx/dy * (top - y2);
- y2 = top;
- } else if (y2 > bottom) {
- x2 -= dx/dy * (y2 - bottom);
- y2 = bottom;
- }
- *line = QLineF(QPointF(x1, y1), QPointF(x2, y2));
- }
- return true;
-}
-
-void QX11PaintEngine::drawLines(const QLine *lines, int lineCount)
-{
- Q_ASSERT(lines);
- Q_ASSERT(lineCount);
- Q_D(QX11PaintEngine);
-
- if (d->has_alpha_brush
- || d->has_alpha_pen
- || d->has_custom_pen
- || (d->cpen.widthF() > 0 && d->has_complex_xform
- && !d->has_non_scaling_xform)
- || (d->render_hints & QPainter::Antialiasing)) {
- for (int i = 0; i < lineCount; ++i) {
- QPainterPath path(lines[i].p1());
- path.lineTo(lines[i].p2());
- drawPath(path);
- }
- return;
- }
-
- if (d->has_pen) {
- for (int i = 0; i < lineCount; ++i) {
- QLineF linef;
- if (d->txop == QTransform::TxNone) {
- linef = lines[i];
- } else {
- linef = d->matrix.map(QLineF(lines[i]));
- }
- if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
- int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
- int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
- int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
-
- XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
- }
- }
- }
-}
-
-void QX11PaintEngine::drawLines(const QLineF *lines, int lineCount)
-{
- Q_ASSERT(lines);
- Q_ASSERT(lineCount);
- Q_D(QX11PaintEngine);
-
- if (d->has_alpha_brush
- || d->has_alpha_pen
- || d->has_custom_pen
- || (d->cpen.widthF() > 0 && d->has_complex_xform
- && !d->has_non_scaling_xform)
- || (d->render_hints & QPainter::Antialiasing)) {
- for (int i = 0; i < lineCount; ++i) {
- QPainterPath path(lines[i].p1());
- path.lineTo(lines[i].p2());
- drawPath(path);
- }
- return;
- }
-
- if (d->has_pen) {
- for (int i = 0; i < lineCount; ++i) {
- QLineF linef = d->matrix.map(lines[i]);
- if (clipLine(&linef, d->polygonClipper.boundingRect())) {
- int x1 = qRound(linef.x1() + aliasedCoordinateDelta);
- int y1 = qRound(linef.y1() + aliasedCoordinateDelta);
- int x2 = qRound(linef.x2() + aliasedCoordinateDelta);
- int y2 = qRound(linef.y2() + aliasedCoordinateDelta);
-
- XDrawLine(d->dpy, d->hd, d->gc, x1, y1, x2, y2);
- }
- }
- }
-}
-
-static inline QLine clipStraightLine(const QRect &clip, const QLine &l)
-{
- if (l.p1().x() == l.p2().x()) {
- int x = qBound(clip.left(), l.p1().x(), clip.right());
- int y1 = qBound(clip.top(), l.p1().y(), clip.bottom());
- int y2 = qBound(clip.top(), l.p2().y(), clip.bottom());
-
- return QLine(x, y1, x, y2);
- } else {
- Q_ASSERT(l.p1().y() == l.p2().y());
-
- int x1 = qBound(clip.left(), l.p1().x(), clip.right());
- int x2 = qBound(clip.left(), l.p2().x(), clip.right());
- int y = qBound(clip.top(), l.p1().y(), clip.bottom());
-
- return QLine(x1, y, x2, y);
- }
-}
-
-void QX11PaintEngine::drawRects(const QRectF *rects, int rectCount)
-{
- Q_D(QX11PaintEngine);
- Q_ASSERT(rects);
- Q_ASSERT(rectCount);
-
- if (rectCount != 1
- || d->has_pen
- || d->has_alpha_brush
- || d->has_complex_xform
- || d->has_custom_pen
- || d->cbrush.style() != Qt::SolidPattern
-#if QT_CONFIG(xrender)
- || complexPictOp(d->composition_mode)
-#endif
- )
- {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
-
- QPoint alignedOffset;
- if (d->txop == QTransform::TxTranslate) {
- QPointF offset(d->matrix.dx(), d->matrix.dy());
- alignedOffset = offset.toPoint();
- if (offset != QPointF(alignedOffset)) {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
- }
-
- const QRectF& r = rects[0];
- QRect alignedRect = r.toAlignedRect();
- if (r != QRectF(alignedRect)) {
- QPaintEngine::drawRects(rects, rectCount);
- return;
- }
- alignedRect.translate(alignedOffset);
-
- QRect clip(d->polygonClipper.boundingRect());
- alignedRect = alignedRect.intersected(clip);
- if (alignedRect.isEmpty())
- return;
-
- // simple-case:
- // the rectangle is pixel-aligned
- // the fill brush is just a solid non-alpha color
- // the painter transform is only integer translation
- // ignore: antialiasing and just XFillRectangles directly
- XRectangle xrect;
- xrect.x = short(alignedRect.x());
- xrect.y = short(alignedRect.y());
- xrect.width = ushort(alignedRect.width());
- xrect.height = ushort(alignedRect.height());
- XFillRectangles(d->dpy, d->hd, d->gc_brush, &xrect, 1);
-}
-
-void QX11PaintEngine::drawRects(const QRect *rects, int rectCount)
-{
- Q_D(QX11PaintEngine);
- Q_ASSERT(rects);
- Q_ASSERT(rectCount);
-
- if (d->has_alpha_pen
- || d->has_complex_xform
- || d->has_custom_pen
- || (d->render_hints & QPainter::Antialiasing))
- {
- for (int i = 0; i < rectCount; ++i) {
- QPainterPath path;
- path.addRect(rects[i]);
- drawPath(path);
- }
- return;
- }
-
- QRect clip(d->polygonClipper.boundingRect());
- QPoint offset(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
-#if QT_CONFIG(xrender)
- ::Picture pict = d->picture;
-
- if (X11->use_xrender && pict && d->has_brush && d->pdev_depth != 1
- && (d->has_texture || d->has_alpha_brush || complexPictOp(d->composition_mode)))
- {
- XRenderColor xc;
- if (!d->has_texture && !d->has_pattern)
- xc = X11->preMultiply(d->cbrush.color());
-
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- if (d->has_pen) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- }
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty())
- continue;
- if (d->has_texture || d->has_pattern) {
- XRenderComposite(d->dpy, d->composition_mode, d->current_brush, 0, pict,
- qRound(r.x() - d->bg_origin.x()), qRound(r.y() - d->bg_origin.y()),
- 0, 0, r.x(), r.y(), r.width(), r.height());
- } else {
- XRenderFillRectangle(d->dpy, d->composition_mode, pict, &xc, r.x(), r.y(), r.width(), r.height());
- }
- if (d->has_pen)
- XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
- }
- } else
-#endif // QT_CONFIG(xrender)
- {
- if (d->has_brush && d->has_pen) {
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty())
- continue;
- d->setupAdaptedOrigin(r.topLeft());
- XFillRectangle(d->dpy, d->hd, d->gc_brush, r.x(), r.y(), r.width(), r.height());
- XDrawRectangle(d->dpy, d->hd, d->gc, r.x(), r.y(), r.width(), r.height());
- }
- d->resetAdaptedOrigin();
- } else {
- QVarLengthArray<XRectangle> xrects(rectCount);
- int numClipped = rectCount;
- for (int i = 0; i < rectCount; ++i) {
- QRect r(rects[i]);
- if (d->txop == QTransform::TxTranslate)
- r.translate(offset);
-
- if (r.width() == 0 || r.height() == 0) {
- --numClipped;
- if (d->has_pen) {
- const QLine l = clipStraightLine(clip, QLine(r.left(), r.top(), r.left() + r.width(), r.top() + r.height()));
- XDrawLine(d->dpy, d->hd, d->gc, l.p1().x(), l.p1().y(), l.p2().x(), l.p2().y());
- }
- continue;
- }
-
- r = r.intersected(clip);
- if (r.isEmpty()) {
- --numClipped;
- continue;
- }
- xrects[i].x = short(r.x());
- xrects[i].y = short(r.y());
- xrects[i].width = ushort(r.width());
- xrects[i].height = ushort(r.height());
- }
- if (numClipped) {
- d->setupAdaptedOrigin(rects[0].topLeft());
- if (d->has_brush)
- XFillRectangles(d->dpy, d->hd, d->gc_brush, xrects.data(), numClipped);
- else if (d->has_pen)
- XDrawRectangles(d->dpy, d->hd, d->gc, xrects.data(), numClipped);
- d->resetAdaptedOrigin();
- }
- }
- }
-}
-
-static inline void setCapStyle(int cap_style, GC gc)
-{
- ulong mask = GCCapStyle;
- XGCValues vals;
- vals.cap_style = cap_style;
- XChangeGC(QXcbX11Info::display(), gc, mask, &vals);
-}
-
-void QX11PaintEngine::drawPoints(const QPoint *points, int pointCount)
-{
- Q_ASSERT(points);
- Q_ASSERT(pointCount);
- Q_D(QX11PaintEngine);
-
- if (!d->has_pen)
- return;
-
- // use the same test here as in drawPath to ensure that we don't use the path fallback
- // and end up in XDrawLines for pens with width <= 1
- if (d->cpen.widthF() > 1.0f
- || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->isCosmeticPen() && d->txop > QTransform::TxTranslate))
- {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapProjecting, d->gc);
- d->cpen.setCapStyle(Qt::SquareCap);
- }
- const QPoint *end = points + pointCount;
- while (points < end) {
- QPainterPath path;
- path.moveTo(*points);
- path.lineTo(points->x()+.005, points->y());
- drawPath(path);
- ++points;
- }
-
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapButt, d->gc);
- d->cpen.setCapStyle(capStyle);
- }
- return;
- }
-
- static const int BUF_SIZE = 1024;
- XPoint xPoints[BUF_SIZE];
- int i = 0, j = 0;
- while (i < pointCount) {
- while (i < pointCount && j < BUF_SIZE) {
- const QPoint &xformed = d->matrix.map(points[i]);
- int x = xformed.x();
- int y = xformed.y();
- if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
- xPoints[j].x = x;
- xPoints[j].y = y;
- ++j;
- }
- ++i;
- }
- if (j)
- XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
-
- j = 0;
- }
-}
-
-void QX11PaintEngine::drawPoints(const QPointF *points, int pointCount)
-{
- Q_ASSERT(points);
- Q_ASSERT(pointCount);
- Q_D(QX11PaintEngine);
-
- if (!d->has_pen)
- return;
-
- // use the same test here as in drawPath to ensure that we don't use the path fallback
- // and end up in XDrawLines for pens with width <= 1
- if (d->cpen.widthF() > 1.0f
- || (X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->isCosmeticPen() && d->txop > QTransform::TxTranslate))
- {
- Qt::PenCapStyle capStyle = d->cpen.capStyle();
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapProjecting, d->gc);
- d->cpen.setCapStyle(Qt::SquareCap);
- }
-
- const QPointF *end = points + pointCount;
- while (points < end) {
- QPainterPath path;
- path.moveTo(*points);
- path.lineTo(points->x() + 0.005, points->y());
- drawPath(path);
- ++points;
- }
- if (capStyle == Qt::FlatCap) {
- setCapStyle(CapButt, d->gc);
- d->cpen.setCapStyle(capStyle);
- }
- return;
- }
-
- static const int BUF_SIZE = 1024;
- XPoint xPoints[BUF_SIZE];
- int i = 0, j = 0;
- while (i < pointCount) {
- while (i < pointCount && j < BUF_SIZE) {
- const QPointF &xformed = d->matrix.map(points[i]);
- int x = qFloor(xformed.x());
- int y = qFloor(xformed.y());
-
- if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) {
- xPoints[j].x = x;
- xPoints[j].y = y;
- ++j;
- }
- ++i;
- }
- if (j)
- XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin);
-
- j = 0;
- }
-}
-
-QPainter::RenderHints QX11PaintEngine::supportedRenderHints() const
-{
-#if QT_CONFIG(xrender)
- if (X11->use_xrender)
- return QPainter::Antialiasing;
-#endif
- return QFlag(0);
-}
-
-void QX11PaintEngine::updateState(const QPaintEngineState &state)
-{
- Q_D(QX11PaintEngine);
- QPaintEngine::DirtyFlags flags = state.state();
-
-
- if (flags & DirtyOpacity) {
- d->opacity = state.opacity();
- // Force update pen/brush as to get proper alpha colors propagated
- flags |= DirtyPen;
- flags |= DirtyBrush;
- }
-
- if (flags & DirtyTransform) updateMatrix(state.transform());
- if (flags & DirtyPen) updatePen(state.pen());
- if (flags & (DirtyBrush | DirtyBrushOrigin)) updateBrush(state.brush(), state.brushOrigin());
- if (flags & DirtyFont) updateFont(state.font());
-
- if (state.state() & DirtyClipEnabled) {
- if (state.isClipEnabled()) {
- QPolygonF clip_poly_dev(d->matrix.map(painter()->clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip);
- } else {
- updateClipRegion_dev(QRegion(), Qt::NoClip);
- }
- }
-
- if (flags & DirtyClipPath) {
- QPolygonF clip_poly_dev(d->matrix.map(state.clipPath().toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon(), state.clipPath().fillRule()),
- state.clipOperation());
- } else if (flags & DirtyClipRegion) {
- extern QPainterPath qt_regionToPath(const QRegion &region);
- QPainterPath clip_path = qt_regionToPath(state.clipRegion());
- QPolygonF clip_poly_dev(d->matrix.map(clip_path.toFillPolygon()));
- QPolygonF clipped_poly_dev;
- d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev);
- updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), state.clipOperation());
- }
- if (flags & DirtyHints) updateRenderHints(state.renderHints());
- if (flags & DirtyCompositionMode) {
- int function = GXcopy;
- if (state.compositionMode() >= QPainter::RasterOp_SourceOrDestination) {
- switch (state.compositionMode()) {
- case QPainter::RasterOp_SourceOrDestination:
- function = GXor;
- break;
- case QPainter::RasterOp_SourceAndDestination:
- function = GXand;
- break;
- case QPainter::RasterOp_SourceXorDestination:
- function = GXxor;
- break;
- case QPainter::RasterOp_NotSourceAndNotDestination:
- function = GXnor;
- break;
- case QPainter::RasterOp_NotSourceOrNotDestination:
- function = GXnand;
- break;
- case QPainter::RasterOp_NotSourceXorDestination:
- function = GXequiv;
- break;
- case QPainter::RasterOp_NotSource:
- function = GXcopyInverted;
- break;
- case QPainter::RasterOp_SourceAndNotDestination:
- function = GXandReverse;
- break;
- case QPainter::RasterOp_NotSourceAndDestination:
- function = GXandInverted;
- break;
- default:
- function = GXcopy;
- }
- }
-#if QT_CONFIG(xrender)
- else {
- d->composition_mode =
- qpainterOpToXrender(state.compositionMode());
- }
-#endif
- XSetFunction(X11->display, d->gc, function);
- XSetFunction(X11->display, d->gc_brush, function);
- }
- d->decidePathFallback();
- d->decideCoordAdjust();
-}
-
-void QX11PaintEngine::updateRenderHints(QPainter::RenderHints hints)
-{
- Q_D(QX11PaintEngine);
- d->render_hints = hints;
-
-#if QT_CONFIG(xrender)
- if (X11->use_xrender && d->picture) {
- XRenderPictureAttributes attrs;
- attrs.poly_edge = (hints & QPainter::Antialiasing) ? PolyEdgeSmooth : PolyEdgeSharp;
- XRenderChangePicture(d->dpy, d->picture, CPPolyEdge, &attrs);
- }
-#endif
-}
-
-void QX11PaintEngine::updatePen(const QPen &pen)
-{
- Q_D(QX11PaintEngine);
- d->cpen = pen;
- int cp = CapButt;
- int jn = JoinMiter;
- int ps = pen.style();
-
- if (d->opacity < 1.0) {
- QColor c = d->cpen.color();
- c.setAlpha(qRound(c.alpha()*d->opacity));
- d->cpen.setColor(c);
- }
-
- d->has_pen = (ps != Qt::NoPen);
- d->has_alpha_pen = (pen.color().alpha() != 255);
-
- switch (pen.capStyle()) {
- case Qt::SquareCap:
- cp = CapProjecting;
- break;
- case Qt::RoundCap:
- cp = CapRound;
- break;
- case Qt::FlatCap:
- default:
- cp = CapButt;
- break;
- }
- switch (pen.joinStyle()) {
- case Qt::BevelJoin:
- jn = JoinBevel;
- break;
- case Qt::RoundJoin:
- jn = JoinRound;
- break;
- case Qt::MiterJoin:
- default:
- jn = JoinMiter;
- break;
- }
-
- d->adapted_pen_origin = false;
-
- char dashes[10]; // custom pen dashes
- int dash_len = 0; // length of dash list
- int xStyle = LineSolid;
-
- /*
- We are emulating Windows here. Windows treats cpen.width() == 1
- (or 0) as a very special case. The fudge variable unifies this
- case with the general case.
- */
- qreal pen_width = pen.widthF();
- int scale = qRound(pen_width < 1 ? 1 : pen_width);
- int space = (pen_width < 1 && pen_width > 0 ? 1 : (2 * scale));
- int dot = 1 * scale;
- int dash = 4 * scale;
-
- d->has_custom_pen = false;
-
- switch (ps) {
- case Qt::NoPen:
- case Qt::SolidLine:
- xStyle = LineSolid;
- break;
- case Qt::DashLine:
- dashes[0] = dash;
- dashes[1] = space;
- dash_len = 2;
- xStyle = LineOnOffDash;
- break;
- case Qt::DotLine:
- dashes[0] = dot;
- dashes[1] = space;
- dash_len = 2;
- xStyle = LineOnOffDash;
- break;
- case Qt::DashDotLine:
- dashes[0] = dash;
- dashes[1] = space;
- dashes[2] = dot;
- dashes[3] = space;
- dash_len = 4;
- xStyle = LineOnOffDash;
- break;
- case Qt::DashDotDotLine:
- dashes[0] = dash;
- dashes[1] = space;
- dashes[2] = dot;
- dashes[3] = space;
- dashes[4] = dot;
- dashes[5] = space;
- dash_len = 6;
- xStyle = LineOnOffDash;
- break;
- case Qt::CustomDashLine:
- d->has_custom_pen = true;
- break;
- }
-
- ulong mask = GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth
- | GCCapStyle | GCJoinStyle | GCLineStyle;
- XGCValues vals;
- vals.graphics_exposures = false;
- if (d->pdev_depth == 1) {
- vals.foreground = qGray(pen.color().rgb()) > 127 ? 0 : 1;
- vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
- } else if (d->pdev->devType() == QInternal::Pixmap && d->pdev_depth == 32
- && X11->use_xrender) {
- vals.foreground = pen.color().rgba();
- vals.background = QColor(Qt::transparent).rgba();
- } else {
- QXcbColormap cmap = QXcbColormap::instance(d->scrn);
- vals.foreground = cmap.pixel(pen.color());
- vals.background = cmap.pixel(QColor(Qt::transparent));
- }
-
-
- vals.line_width = qRound(pen.widthF());
- vals.cap_style = cp;
- vals.join_style = jn;
- vals.line_style = xStyle;
-
- XChangeGC(d->dpy, d->gc, mask, &vals);
-
- if (dash_len) { // make dash list
- XSetDashes(d->dpy, d->gc, 0, dashes, dash_len);
- }
-
- if (!d->has_clipping) { // if clipping is set the paintevent clip region is merged with the clip region
- QRegion sysClip = d->use_sysclip ? systemClip() : QRegion();
- if (!sysClip.isEmpty())
- x11SetClipRegion(d->dpy, d->gc, 0, d->picture, sysClip);
- else
- x11ClearClipRegion(d->dpy, d->gc, 0, d->picture);
- }
-}
-
-void QX11PaintEngine::updateBrush(const QBrush &brush, const QPointF &origin)
-{
- Q_D(QX11PaintEngine);
- d->cbrush = brush;
- d->bg_origin = origin;
- d->adapted_brush_origin = false;
-#if QT_CONFIG(xrender)
- d->current_brush = 0;
-#endif
- if (d->opacity < 1.0) {
- QColor c = d->cbrush.color();
- c.setAlpha(qRound(c.alpha()*d->opacity));
- d->cbrush.setColor(c);
- }
-
- int s = FillSolid;
- int bs = d->cbrush.style();
- d->has_brush = (bs != Qt::NoBrush);
- d->has_pattern = bs >= Qt::Dense1Pattern && bs <= Qt::DiagCrossPattern;
- d->has_texture = bs == Qt::TexturePattern;
- d->has_alpha_brush = brush.color().alpha() != 255;
- d->has_alpha_texture = d->has_texture && d->cbrush.texture().hasAlphaChannel();
-
- ulong mask = GCForeground | GCBackground | GCGraphicsExposures
- | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle;
- XGCValues vals;
- vals.graphics_exposures = false;
- if (d->pdev_depth == 1) {
- vals.foreground = qGray(d->cbrush.color().rgb()) > 127 ? 0 : 1;
- vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1;
- } else if (X11->use_xrender && d->pdev->devType() == QInternal::Pixmap
- && d->pdev_depth == 32) {
- vals.foreground = d->cbrush.color().rgba();
- vals.background = QColor(Qt::transparent).rgba();
- } else {
- QXcbColormap cmap = QXcbColormap::instance(d->scrn);
- vals.foreground = cmap.pixel(d->cbrush.color());
- vals.background = cmap.pixel(QColor(Qt::transparent));
-
- if (!X11->use_xrender && d->has_brush && !d->has_pattern && !brush.isOpaque()) {
- QPixmap pattern = qt_patternForAlpha(brush.color().alpha(), d->scrn);
- mask |= GCStipple;
- vals.stipple = qt_x11PixmapHandle(pattern);
- s = FillStippled;
- d->adapted_brush_origin = true;
- }
- }
- vals.cap_style = CapButt;
- vals.join_style = JoinMiter;
- vals.line_style = LineSolid;
-
- if (d->has_pattern || d->has_texture) {
- if (bs == Qt::TexturePattern) {
- d->brush_pm = qt_toX11Pixmap(d->cbrush.texture());
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, qt_x11PictureHandle(d->brush_pm), CPRepeat, &attrs);
- QX11PlatformPixmap *data = static_cast<QX11PlatformPixmap*>(d->brush_pm.handle());
- if (data->mask_picture)
- XRenderChangePicture(d->dpy, data->mask_picture, CPRepeat, &attrs);
- }
-#endif
- } else {
- d->brush_pm = qt_toX11Pixmap(qt_pixmapForBrush(bs, true));
- }
- qt_x11SetScreen(d->brush_pm, d->scrn);
- if (d->brush_pm.depth() == 1) {
- mask |= GCStipple;
- vals.stipple = qt_x11PixmapHandle(d->brush_pm);
- s = FillStippled;
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- d->bitmap_texture = QPixmap(d->brush_pm.size());
- d->bitmap_texture.fill(Qt::transparent);
- d->bitmap_texture = qt_toX11Pixmap(d->bitmap_texture);
- qt_x11SetScreen(d->bitmap_texture, d->scrn);
-
- ::Picture src = X11->getSolidFill(d->scrn, d->cbrush.color());
- XRenderComposite(d->dpy, PictOpSrc, src, qt_x11PictureHandle(d->brush_pm),
- qt_x11PictureHandle(d->bitmap_texture),
- 0, 0, d->brush_pm.width(), d->brush_pm.height(),
- 0, 0, d->brush_pm.width(), d->brush_pm.height());
-
- XRenderPictureAttributes attrs;
- attrs.repeat = true;
- XRenderChangePicture(d->dpy, qt_x11PictureHandle(d->bitmap_texture), CPRepeat, &attrs);
-
- d->current_brush = qt_x11PictureHandle(d->bitmap_texture);
- }
-#endif
- } else {
- mask |= GCTile;
-#if QT_CONFIG(xrender)
- if (d->pdev_depth == 32 && d->brush_pm.depth() != 32) {
- d->brush_pm.detach();
- QX11PlatformPixmap *brushData = static_cast<QX11PlatformPixmap*>(d->brush_pm.handle());
- brushData->convertToARGB32();
- }
-#endif
- vals.tile = (d->brush_pm.depth() == d->pdev_depth
- ? qt_x11PixmapHandle(d->brush_pm)
- : static_cast<QX11PlatformPixmap*>(d->brush_pm.handle())->x11ConvertToDefaultDepth());
- s = FillTiled;
-#if QT_CONFIG(xrender)
- d->current_brush = qt_x11PictureHandle(d->cbrush.texture());
-#endif
- }
-
- mask |= GCTileStipXOrigin | GCTileStipYOrigin;
- vals.ts_x_origin = qRound(origin.x());
- vals.ts_y_origin = qRound(origin.y());
- }
-#if QT_CONFIG(xrender)
- else if (d->has_alpha_brush) {
- d->current_brush = X11->getSolidFill(d->scrn, d->cbrush.color());
- }
-#endif
-
- vals.fill_style = s;
- XChangeGC(d->dpy, d->gc_brush, mask, &vals);
- if (!d->has_clipping) {
- QRegion sysClip = d->use_sysclip ? systemClip() : QRegion();
- if (!sysClip.isEmpty())
- x11SetClipRegion(d->dpy, d->gc_brush, 0, d->picture, sysClip);
- else
- x11ClearClipRegion(d->dpy, d->gc_brush, 0, d->picture);
- }
-}
-
-void QX11PaintEngine::drawEllipse(const QRectF &rect)
-{
- QRect aligned = rect.toAlignedRect();
- if (aligned == rect)
- drawEllipse(aligned);
- else
- QPaintEngine::drawEllipse(rect);
-}
-
-void QX11PaintEngine::drawEllipse(const QRect &rect)
-{
- if (rect.isEmpty()) {
- drawRects(&rect, 1);
- return;
- }
-
- Q_D(QX11PaintEngine);
- QRect devclip(SHRT_MIN, SHRT_MIN, SHRT_MAX*2 - 1, SHRT_MAX*2 - 1);
- QRect r(rect);
- if (d->txop < QTransform::TxRotate) {
- r = d->matrix.mapRect(rect);
- } else if (d->txop == QTransform::TxRotate && rect.width() == rect.height()) {
- QPainterPath path;
- path.addEllipse(rect);
- r = d->matrix.map(path).boundingRect().toRect();
- }
-
- if (d->has_alpha_brush || d->has_alpha_pen || d->has_custom_pen || (d->render_hints & QPainter::Antialiasing)
- || d->has_alpha_texture || devclip.intersected(r) != r
- || (d->has_complex_xform
- && !(d->has_non_scaling_xform && rect.width() == rect.height())))
- {
- QPainterPath path;
- path.addEllipse(rect);
- drawPath(path);
- return;
- }
-
- int x = r.x();
- int y = r.y();
- int w = r.width();
- int h = r.height();
- if (w < 1 || h < 1)
- return;
- if (w == 1 && h == 1) {
- XDrawPoint(d->dpy, d->hd, d->has_pen ? d->gc : d->gc_brush, x, y);
- return;
- }
- d->setupAdaptedOrigin(rect.topLeft());
- if (d->has_brush) { // draw filled ellipse
- XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64);
- if (!d->has_pen) // make smoother outline
- XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64);
- }
- if (d->has_pen) // draw outline
- XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64);
- d->resetAdaptedOrigin();
-}
-
-
-
-void QX11PaintEnginePrivate::fillPolygon_translated(const QPointF *polygonPoints, int pointCount,
- QX11PaintEnginePrivate::GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode)
-{
-
- QVarLengthArray<QPointF> translated_points(pointCount);
- QPointF offset(matrix.dx(), matrix.dy());
-
- qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
- if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing))
- offset += QPointF(aliasedCoordinateDelta, aliasedCoordinateDelta);
-
- for (int i = 0; i < pointCount; ++i) {
- translated_points[i] = polygonPoints[i] + offset;
-
- translated_points[i].rx() = qRound(translated_points[i].x()) + offs;
- translated_points[i].ry() = qRound(translated_points[i].y()) + offs;
- }
-
- fillPolygon_dev(translated_points.data(), pointCount, gcMode, mode);
-}
-
-#if QT_CONFIG(xrender)
-static void qt_XRenderCompositeTrapezoids(Display *dpy,
- int op,
- Picture src,
- Picture dst,
- _Xconst XRenderPictFormat *maskFormat,
- int xSrc,
- int ySrc,
- const XTrapezoid *traps, int size)
-{
- const int MAX_TRAPS = 50000;
- while (size) {
- int to_draw = size;
- if (to_draw > MAX_TRAPS)
- to_draw = MAX_TRAPS;
- XRenderCompositeTrapezoids(dpy, op, src, dst,
- maskFormat,
- xSrc, ySrc,
- traps, to_draw);
- size -= to_draw;
- traps += to_draw;
- }
-}
-#endif
-
-void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount,
- QX11PaintEnginePrivate::GCMode gcMode,
- QPaintEngine::PolygonDrawMode mode)
-{
- Q_Q(QX11PaintEngine);
-
- int clippedCount = 0;
- qt_float_point *clippedPoints = 0;
-
-#if QT_CONFIG(xrender)
- //can change if we switch to pen if gcMode != BrushGC
- bool has_fill_texture = has_texture;
- bool has_fill_pattern = has_pattern;
- ::Picture src;
-#endif
- QBrush fill;
- GC fill_gc;
- if (gcMode == BrushGC) {
- fill = cbrush;
- fill_gc = gc_brush;
-#if QT_CONFIG(xrender)
- if (current_brush)
- src = current_brush;
- else
- src = X11->getSolidFill(scrn, fill.color());
-#endif
- } else {
- fill = QBrush(cpen.brush());
- fill_gc = gc;
-#if QT_CONFIG(xrender)
- //we use the pens brush
- has_fill_texture = (fill.style() == Qt::TexturePattern);
- has_fill_pattern = (fill.style() >= Qt::Dense1Pattern && fill.style() <= Qt::DiagCrossPattern);
- if (has_fill_texture)
- src = qt_x11PictureHandle(fill.texture());
- else if (has_fill_pattern)
- src = getPatternFill(scrn, fill);
- else
- src = X11->getSolidFill(scrn, fill.color());
-#endif
- }
-
- polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
- &clippedPoints, &clippedCount);
-
-#if QT_CONFIG(xrender)
- bool solid_fill = fill.color().alpha() == 255;
- if (has_fill_texture && fill.texture().depth() == 1 && solid_fill) {
- has_fill_texture = false;
- has_fill_pattern = true;
- }
-
- bool antialias = render_hints & QPainter::Antialiasing;
-
- if (X11->use_xrender
- && picture
- && !has_fill_pattern
- && (clippedCount > 0)
- && (fill.style() != Qt::NoBrush)
- && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush))
- {
- tessellator->tessellate((QPointF *)clippedPoints, clippedCount,
- mode == QPaintEngine::WindingMode);
- if (tessellator->size > 0) {
- XRenderPictureAttributes attrs;
- attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp;
- XRenderChangePicture(dpy, picture, CPPolyEdge, &attrs);
- int x_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.x) - bg_origin.x());
- int y_offset = int(XFixedToDouble(tessellator->traps[0].left.p1.y) - bg_origin.y());
- qt_XRenderCompositeTrapezoids(dpy, composition_mode, src, picture,
- antialias
- ? XRenderFindStandardFormat(dpy, PictStandardA8)
- : XRenderFindStandardFormat(dpy, PictStandardA1),
- x_offset, y_offset,
- tessellator->traps, tessellator->size);
- tessellator->done();
- }
- } else
-#endif
- if (fill.style() != Qt::NoBrush) {
- if (clippedCount > 200000) {
- QPolygon poly;
- for (int i = 0; i < clippedCount; ++i)
- poly << QPoint(qFloor(clippedPoints[i].x), qFloor(clippedPoints[i].y));
-
- const QRect bounds = poly.boundingRect();
- const QRect aligned = bounds
- & QRect(QPoint(), QSize(pdev->width(), pdev->height()));
-
- QImage img(aligned.size(), QImage::Format_ARGB32_Premultiplied);
- img.fill(0);
-
- QPainter painter(&img);
- painter.translate(-aligned.x(), -aligned.y());
- painter.setPen(Qt::NoPen);
- painter.setBrush(fill);
- if (gcMode == BrushGC)
- painter.setBrushOrigin(q->painter()->brushOriginF());
- painter.drawPolygon(poly);
- painter.end();
-
- q->drawImage(aligned, img, img.rect(), Qt::AutoColor);
- } else if (clippedCount > 0) {
- QVarLengthArray<XPoint> xpoints(clippedCount);
- for (int i = 0; i < clippedCount; ++i) {
- xpoints[i].x = qFloor(clippedPoints[i].x);
- xpoints[i].y = qFloor(clippedPoints[i].y);
- }
- if (mode == QPaintEngine::WindingMode)
- XSetFillRule(dpy, fill_gc, WindingRule);
- setupAdaptedOrigin(QPoint(xpoints[0].x, xpoints[0].y));
- XFillPolygon(dpy, hd, fill_gc,
- xpoints.data(), clippedCount,
- mode == QPaintEngine::ConvexMode ? Convex : Complex, CoordModeOrigin);
- resetAdaptedOrigin();
- if (mode == QPaintEngine::WindingMode)
- XSetFillRule(dpy, fill_gc, EvenOddRule);
- }
- }
-}
-
-void QX11PaintEnginePrivate::strokePolygon_translated(const QPointF *polygonPoints, int pointCount, bool close)
-{
- QVarLengthArray<QPointF> translated_points(pointCount);
- QPointF offset(matrix.dx(), matrix.dy());
- for (int i = 0; i < pointCount; ++i)
- translated_points[i] = polygonPoints[i] + offset;
- strokePolygon_dev(translated_points.data(), pointCount, close);
-}
-
-void QX11PaintEnginePrivate::strokePolygon_dev(const QPointF *polygonPoints, int pointCount, bool close)
-{
- int clippedCount = 0;
- qt_float_point *clippedPoints = 0;
- polygonClipper.clipPolygon((qt_float_point *) polygonPoints, pointCount,
- &clippedPoints, &clippedCount, close);
-
- if (clippedCount > 0) {
- QVarLengthArray<XPoint> xpoints(clippedCount);
- for (int i = 0; i < clippedCount; ++i) {
- xpoints[i].x = qRound(clippedPoints[i].x + aliasedCoordinateDelta);
- xpoints[i].y = qRound(clippedPoints[i].y + aliasedCoordinateDelta);
- }
- uint numberPoints = qMin(clippedCount, xlibMaxLinePoints);
- XPoint *pts = xpoints.data();
- XDrawLines(dpy, hd, gc, pts, numberPoints, CoordModeOrigin);
- pts += numberPoints;
- clippedCount -= numberPoints;
- numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
- while (clippedCount) {
- XDrawLines(dpy, hd, gc, pts-1, numberPoints+1, CoordModeOrigin);
- pts += numberPoints;
- clippedCount -= numberPoints;
- numberPoints = qMin(clippedCount, xlibMaxLinePoints-1);
- }
- }
-}
-
-void QX11PaintEngine::drawPolygon(const QPointF *polygonPoints, int pointCount, PolygonDrawMode mode)
-{
- Q_D(QX11PaintEngine);
-
- if (d->use_path_fallback) {
- QPainterPath path(polygonPoints[0]);
- for (int i = 1; i < pointCount; ++i)
- path.lineTo(polygonPoints[i]);
- if (mode == PolylineMode) {
- QBrush oldBrush = d->cbrush;
- d->cbrush = QBrush(Qt::NoBrush);
- path.setFillRule(Qt::WindingFill);
- drawPath(path);
- d->cbrush = oldBrush;
- } else {
- path.setFillRule(mode == OddEvenMode ? Qt::OddEvenFill : Qt::WindingFill);
- path.closeSubpath();
- drawPath(path);
- }
- return;
- }
- if (mode != PolylineMode && d->has_brush)
- d->fillPolygon_translated(polygonPoints, pointCount, QX11PaintEnginePrivate::BrushGC, mode);
-
- if (d->has_pen)
- d->strokePolygon_translated(polygonPoints, pointCount, mode != PolylineMode);
-}
-
-
-void QX11PaintEnginePrivate::fillPath(const QPainterPath &path, QX11PaintEnginePrivate::GCMode gc_mode, bool transform)
-{
- qreal offs = adjust_coords ? aliasedCoordinateDelta : 0.0;
-
- QPainterPath clippedPath;
- QPainterPath clipPath;
- clipPath.addRect(polygonClipper.boundingRect());
-
- if (transform)
- clippedPath = (path*matrix).intersected(clipPath);
- else
- clippedPath = path.intersected(clipPath);
-
- QList<QPolygonF> polys = clippedPath.toFillPolygons();
- for (int i = 0; i < polys.size(); ++i) {
- QVarLengthArray<QPointF> translated_points(polys.at(i).size());
-
- for (int j = 0; j < polys.at(i).size(); ++j) {
- translated_points[j] = polys.at(i).at(j);
- if (!X11->use_xrender || !(render_hints & QPainter::Antialiasing)) {
- translated_points[j].rx() = qRound(translated_points[j].rx() + aliasedCoordinateDelta) + offs;
- translated_points[j].ry() = qRound(translated_points[j].ry() + aliasedCoordinateDelta) + offs;
- }
- }
-
- fillPolygon_dev(translated_points.data(), polys.at(i).size(), gc_mode,
- path.fillRule() == Qt::OddEvenFill ? QPaintEngine::OddEvenMode : QPaintEngine::WindingMode);
- }
-}
-
-void QX11PaintEngine::drawPath(const QPainterPath &path)
-{
- Q_D(QX11PaintEngine);
- if (path.isEmpty())
- return;
-
- if (d->has_brush)
- d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true);
- if (d->has_pen
- && ((X11->use_xrender && (d->has_alpha_pen || (d->render_hints & QPainter::Antialiasing)))
- || (!d->isCosmeticPen() && d->txop > QTransform::TxTranslate
- && !d->has_non_scaling_xform)
- || (d->cpen.style() == Qt::CustomDashLine))) {
- QPainterPathStroker stroker;
- if (d->cpen.style() == Qt::CustomDashLine) {
- stroker.setDashPattern(d->cpen.dashPattern());
- stroker.setDashOffset(d->cpen.dashOffset());
- } else {
- stroker.setDashPattern(d->cpen.style());
- }
- stroker.setCapStyle(d->cpen.capStyle());
- stroker.setJoinStyle(d->cpen.joinStyle());
- QPainterPath stroke;
- qreal width = d->cpen.widthF();
- QPolygonF poly;
- QRectF deviceRect(0, 0, d->pdev->width(), d->pdev->height());
- // necessary to get aliased alphablended primitives to be drawn correctly
- if (d->isCosmeticPen() || d->has_scaling_xform) {
- if (d->isCosmeticPen())
- stroker.setWidth(width == 0 ? 1 : width);
- else
- stroker.setWidth(width * d->xform_scale);
- stroker.d_ptr->stroker.setClipRect(deviceRect);
- stroke = stroker.createStroke(path * d->matrix);
- if (stroke.isEmpty())
- return;
- stroke.setFillRule(Qt::WindingFill);
- d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, false);
- } else {
- stroker.setWidth(width);
- stroker.d_ptr->stroker.setClipRect(d->matrix.inverted().mapRect(deviceRect));
- stroke = stroker.createStroke(path);
- if (stroke.isEmpty())
- return;
- stroke.setFillRule(Qt::WindingFill);
- d->fillPath(stroke, QX11PaintEnginePrivate::PenGC, true);
- }
- } else if (d->has_pen) {
- // if we have a cosmetic pen - use XDrawLine() for speed
- QList<QPolygonF> polys = path.toSubpathPolygons(d->matrix);
- for (int i = 0; i < polys.size(); ++i)
- d->strokePolygon_dev(polys.at(i).data(), polys.at(i).size(), false);
- }
-}
-
-Q_GUI_EXPORT void qt_x11_drawImage(const QRect &rect, const QPoint &pos, const QImage &image,
- Drawable hd, GC gc, Display *dpy, Visual *visual, int depth)
-{
- Q_ASSERT(image.format() == QImage::Format_RGB32);
- Q_ASSERT(image.depth() == 32);
-
- XImage *xi;
- // Note: this code assumes either RGB or BGR, 8 bpc server layouts
- const uint red_mask = (uint) visual->red_mask;
- bool bgr_layout = (red_mask == 0xff);
-
- const int w = rect.width();
- const int h = rect.height();
-
- QImage im;
- int image_byte_order = ImageByteOrder(QXcbX11Info::display());
- if ((QSysInfo::ByteOrder == QSysInfo::BigEndian && ((image_byte_order == LSBFirst) || bgr_layout))
- || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)
- || (image_byte_order == LSBFirst && bgr_layout))
- {
- im = image.copy(rect);
- const qsizetype iw = im.bytesPerLine() / 4;
- uint *data = (uint *)im.bits();
- for (int i=0; i < h; i++) {
- uint *p = data;
- uint *end = p + w;
- if (bgr_layout && image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian) {
- while (p < end) {
- *p = ((*p << 8) & 0xffffff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- } else if ((image_byte_order == LSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
- || (image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::LittleEndian)) {
- while (p < end) {
- *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
- | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- } else if ((image_byte_order == MSBFirst && QSysInfo::ByteOrder == QSysInfo::BigEndian)
- || (image_byte_order == LSBFirst && bgr_layout))
- {
- while (p < end) {
- *p = ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff)
- | ((*p ) & 0xff00ff00);
- p++;
- }
- }
- data += iw;
- }
- xi = XCreateImage(dpy, visual, depth, ZPixmap,
- 0, (char *) im.bits(), w, h, 32, im.bytesPerLine());
- } else {
- xi = XCreateImage(dpy, visual, depth, ZPixmap,
- 0, (char *) image.scanLine(rect.y())+rect.x()*sizeof(uint), w, h, 32, image.bytesPerLine());
- }
- XPutImage(dpy, hd, gc, xi, 0, 0, pos.x(), pos.y(), w, h);
- xi->data = 0; // QImage owns these bits
- XDestroyImage(xi);
-}
-
-void QX11PaintEngine::drawImage(const QRectF &r, const QImage &image, const QRectF &sr, Qt::ImageConversionFlags flags)
-{
- Q_D(QX11PaintEngine);
-
- if (image.format() == QImage::Format_RGB32
- && d->pdev_depth >= 24 && image.depth() == 32
- && r.size() == sr.size())
- {
- int sx = qRound(sr.x());
- int sy = qRound(sr.y());
- int x = qRound(r.x());
- int y = qRound(r.y());
- int w = qRound(r.width());
- int h = qRound(r.height());
-
- qt_x11_drawImage(QRect(sx, sy, w, h), QPoint(x, y), image, d->hd, d->gc, d->dpy,
- (Visual *)d->xinfo->visual(), d->pdev_depth);
- } else {
- QPaintEngine::drawImage(r, image, sr, flags);
- }
-}
-
-void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRectF &_sr)
-{
- Q_D(QX11PaintEngine);
- QRectF sr = _sr;
- int x = qRound(r.x());
- int y = qRound(r.y());
- int sx = qRound(sr.x());
- int sy = qRound(sr.y());
- int sw = qRound(sr.width());
- int sh = qRound(sr.height());
-
- QPixmap pixmap = qt_toX11Pixmap(px);
- if (pixmap.isNull())
- return;
-
- if ((d->xinfo && d->xinfo->screen() != qt_x11Info(pixmap).screen())
- || (qt_x11Info(pixmap).screen() != DefaultScreen(QXcbX11Info::display()))) {
- qt_x11SetScreen(pixmap, d->xinfo ? d->xinfo->screen() : DefaultScreen(X11->display));
- }
-
- qt_x11SetDefaultScreen(qt_x11Info(pixmap).screen());
-
-#if QT_CONFIG(xrender)
- ::Picture src_pict = qt_x11PictureHandle(pixmap);
- if (src_pict && d->picture) {
- const int pDepth = pixmap.depth();
- if (pDepth == 1 && (d->has_alpha_pen)) {
- qt_render_bitmap(d->dpy, d->scrn, src_pict, d->picture,
- sx, sy, x, y, sw, sh, d->cpen);
- return;
- } else if (pDepth != 1 && (pDepth == 32 || pDepth != d->pdev_depth)) {
- XRenderComposite(d->dpy, d->composition_mode,
- src_pict, 0, d->picture, sx, sy, 0, 0, x, y, sw, sh);
- return;
- }
- }
-#endif
-
- bool mono_src = pixmap.depth() == 1;
- bool mono_dst = d->pdev_depth == 1;
- bool restore_clip = false;
-
- if (static_cast<QX11PlatformPixmap*>(pixmap.handle())->x11_mask) { // pixmap has a mask
- QBitmap comb(sw, sh);
- GC cgc = XCreateGC(d->dpy, qt_x11PixmapHandle(comb), 0, 0);
- XSetForeground(d->dpy, cgc, 0);
- XFillRectangle(d->dpy, qt_x11PixmapHandle(comb), cgc, 0, 0, sw, sh);
- XSetBackground(d->dpy, cgc, 0);
- XSetForeground(d->dpy, cgc, 1);
- if (!d->crgn.isEmpty()) {
- QList<XRectangle> rects = qt_region_to_xrectangles(d->crgn);
- XSetClipRectangles(d->dpy, cgc, -x, -y, rects.data(), rects.size(), Unsorted);
- } else if (d->has_clipping) {
- XSetClipRectangles(d->dpy, cgc, 0, 0, 0, 0, Unsorted);
- }
- XSetFillStyle(d->dpy, cgc, FillOpaqueStippled);
- XSetTSOrigin(d->dpy, cgc, -sx, -sy);
- XSetStipple(d->dpy, cgc,
- static_cast<QX11PlatformPixmap*>(pixmap.handle())->x11_mask);
- XFillRectangle(d->dpy, qt_x11PixmapHandle(comb), cgc, 0, 0, sw, sh);
- XFreeGC(d->dpy, cgc);
-
- XSetClipOrigin(d->dpy, d->gc, x, y);
- XSetClipMask(d->dpy, d->gc, qt_x11PixmapHandle(comb));
- restore_clip = true;
- }
-
- if (mono_src) {
- if (!d->crgn.isEmpty()) {
- Pixmap comb = XCreatePixmap(d->dpy, d->hd, sw, sh, 1);
- GC cgc = XCreateGC(d->dpy, comb, 0, 0);
- XSetForeground(d->dpy, cgc, 0);
- XFillRectangle(d->dpy, comb, cgc, 0, 0, sw, sh);
- QList<XRectangle> rects = qt_region_to_xrectangles(d->crgn);
- XSetClipRectangles(d->dpy, cgc, -x, -y, rects.data(), rects.size(), Unsorted);
- XCopyArea(d->dpy, qt_x11PixmapHandle(pixmap), comb, cgc, sx, sy, sw, sh, 0, 0);
- XFreeGC(d->dpy, cgc);
-
- XSetClipMask(d->dpy, d->gc, comb);
- XSetClipOrigin(d->dpy, d->gc, x, y);
- XFreePixmap(d->dpy, comb);
- } else {
- XSetClipMask(d->dpy, d->gc, qt_x11PixmapHandle(pixmap));
- XSetClipOrigin(d->dpy, d->gc, x - sx, y - sy);
- }
-
- if (mono_dst) {
- XSetForeground(d->dpy, d->gc, qGray(d->cpen.color().rgb()) > 127 ? 0 : 1);
- } else {
- QXcbColormap cmap = QXcbColormap::instance(d->scrn);
- XSetForeground(d->dpy, d->gc, cmap.pixel(d->cpen.color()));
- }
- XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh);
- restore_clip = true;
- } else if (mono_dst && !mono_src) {
- QBitmap bitmap = QBitmap::fromPixmap(pixmap);
- XCopyArea(d->dpy, qt_x11PixmapHandle(bitmap), d->hd, d->gc, sx, sy, sw, sh, x, y);
- } else {
- XCopyArea(d->dpy, qt_x11PixmapHandle(pixmap), d->hd, d->gc, sx, sy, sw, sh, x, y);
- }
-
- if (d->pdev->devType() == QInternal::Pixmap) {
- const QPixmap *px = static_cast<const QPixmap*>(d->pdev);
- Pixmap src_mask = static_cast<QX11PlatformPixmap*>(pixmap.handle())->x11_mask;
- Pixmap dst_mask = static_cast<QX11PlatformPixmap*>(px->handle())->x11_mask;
- if (dst_mask) {
- GC cgc = XCreateGC(d->dpy, dst_mask, 0, 0);
- XSetClipOrigin(d->dpy, cgc, x, y);
- XSetClipMask(d->dpy, cgc, src_mask);
- if (src_mask) { // copy src mask into dst mask
- XCopyArea(d->dpy, src_mask, dst_mask, cgc, sx, sy, sw, sh, x, y);
- } else { // no src mask, but make sure the area copied is opaque in dest
- XSetBackground(d->dpy, cgc, 0);
- XSetForeground(d->dpy, cgc, 1);
- XFillRectangle(d->dpy, dst_mask, cgc, x, y, sw, sh);
- }
- XFreeGC(d->dpy, cgc);
- }
- }
-
- if (restore_clip) {
- XSetClipOrigin(d->dpy, d->gc, 0, 0);
- QList<XRectangle> rects = qt_region_to_xrectangles(d->crgn);
- if (rects.isEmpty())
- XSetClipMask(d->dpy, d->gc, XNone);
- else
- XSetClipRectangles(d->dpy, d->gc, 0, 0, rects.data(), rects.size(), Unsorted);
- }
-}
-
-void QX11PaintEngine::updateMatrix(const QTransform &mtx)
-{
- Q_D(QX11PaintEngine);
- d->txop = mtx.type();
- d->matrix = mtx;
-
- d->has_complex_xform = (d->txop > QTransform::TxTranslate);
-
- extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale);
- bool scaling = qt_scaleForTransform(d->matrix, &d->xform_scale);
- d->has_scaling_xform = scaling && d->xform_scale != 1.0;
- d->has_non_scaling_xform = scaling && d->xform_scale == 1.0;
-}
-
-/*
- NB! the clip region is expected to be in dev coordinates
-*/
-void QX11PaintEngine::updateClipRegion_dev(const QRegion &clipRegion, Qt::ClipOperation op)
-{
- Q_D(QX11PaintEngine);
- QRegion sysClip = d->use_sysclip ? systemClip() : QRegion();
- if (op == Qt::NoClip) {
- d->has_clipping = false;
- d->crgn = sysClip;
- if (!sysClip.isEmpty()) {
- x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, sysClip);
- } else {
- x11ClearClipRegion(d->dpy, d->gc, d->gc_brush, d->picture);
- }
- return;
- }
-
- switch (op) {
- case Qt::IntersectClip:
- if (d->has_clipping) {
- d->crgn &= clipRegion;
- break;
- }
- // fall through
- case Qt::ReplaceClip:
- if (!sysClip.isEmpty())
- d->crgn = clipRegion.intersected(sysClip);
- else
- d->crgn = clipRegion;
- break;
-// case Qt::UniteClip:
-// d->crgn |= clipRegion;
-// if (!sysClip.isEmpty())
-// d->crgn = d->crgn.intersected(sysClip);
-// break;
- default:
- break;
- }
- d->has_clipping = true;
- x11SetClipRegion(d->dpy, d->gc, d->gc_brush, d->picture, d->crgn);
-}
-
-void QX11PaintEngine::updateFont(const QFont &)
-{
-}
-
-Drawable QX11PaintEngine::handle() const
-{
- Q_D(const QX11PaintEngine);
- Q_ASSERT(isActive());
- Q_ASSERT(d->hd);
- return d->hd;
-}
-
-extern void qt_draw_tile(QPaintEngine *, qreal, qreal, qreal, qreal, const QPixmap &,
- qreal, qreal);
-
-void QX11PaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p)
-{
- int x = qRound(r.x());
- int y = qRound(r.y());
- int w = qRound(r.width());
- int h = qRound(r.height());
- int sx = qRound(p.x());
- int sy = qRound(p.y());
-
- bool mono_src = pixmap.depth() == 1;
- Q_D(QX11PaintEngine);
-
- if ((d->xinfo && d->xinfo->screen() != qt_x11Info(pixmap).screen())
- || (qt_x11Info(pixmap).screen() != DefaultScreen(QXcbX11Info::display()))) {
- QPixmap* p = const_cast<QPixmap *>(&pixmap);
- qt_x11SetScreen(*p, d->xinfo ? d->xinfo->screen() : DefaultScreen(QXcbX11Info::display()));
- }
-
- qt_x11SetDefaultScreen(qt_x11Info(pixmap).screen());
-
-#if QT_CONFIG(xrender)
- if (X11->use_xrender && d->picture && qt_x11PictureHandle(pixmap)) {
- const int numTiles = (w / pixmap.width()) * (h / pixmap.height());
- if (numTiles < 100) {
- // this is essentially qt_draw_tile(), inlined for
- // the XRenderComposite call
- int yPos, xPos, drawH, drawW, yOff, xOff;
- yPos = y;
- yOff = sy;
- while (yPos < y + h) {
- drawH = pixmap.height() - yOff; // Cropping first row
- if (yPos + drawH > y + h) // Cropping last row
- drawH = y + h - yPos;
- xPos = x;
- xOff = sx;
- while (xPos < x + w) {
- drawW = pixmap.width() - xOff; // Cropping first column
- if (xPos + drawW > x + w) // Cropping last column
- drawW = x + w - xPos;
- if (mono_src) {
- qt_render_bitmap(d->dpy, d->scrn, qt_x11PictureHandle(pixmap), d->picture,
- xOff, yOff, xPos, yPos, drawW, drawH, d->cpen);
- } else {
- XRenderComposite(d->dpy, d->composition_mode,
- qt_x11PictureHandle(pixmap), XNone, d->picture,
- xOff, yOff, 0, 0, xPos, yPos, drawW, drawH);
- }
- xPos += drawW;
- xOff = 0;
- }
- yPos += drawH;
- yOff = 0;
- }
- } else {
- w = qMin(w, d->pdev->width() - x);
- h = qMin(h, d->pdev->height() - y);
- if (w <= 0 || h <= 0)
- return;
-
- const int pw = w + sx;
- const int ph = h + sy;
- QPixmap pm(pw, ph);
- if (pixmap.hasAlpha() || mono_src)
- pm.fill(Qt::transparent);
-
- const int mode = pixmap.hasAlpha() ? PictOpOver : PictOpSrc;
- const ::Picture pmPicture = qt_x11PictureHandle(pm);
-
- // first tile
- XRenderComposite(d->dpy, mode,
- qt_x11PictureHandle(pixmap), XNone, pmPicture,
- 0, 0, 0, 0, 0, 0, qMin(pw, pixmap.width()), qMin(ph, pixmap.height()));
-
- // first row of tiles
- int xPos = pixmap.width();
- const int sh = qMin(ph, pixmap.height());
- while (xPos < pw) {
- const int sw = qMin(xPos, pw - xPos);
- XRenderComposite(d->dpy, mode,
- pmPicture, XNone, pmPicture,
- 0, 0, 0, 0, xPos, 0, sw, sh);
- xPos *= 2;
- }
-
- // remaining rows
- int yPos = pixmap.height();
- const int sw = pw;
- while (yPos < ph) {
- const int sh = qMin(yPos, ph - yPos);
- XRenderComposite(d->dpy, mode,
- pmPicture, XNone, pmPicture,
- 0, 0, 0, 0, 0, yPos, sw, sh);
- yPos *= 2;
- }
-
- // composite
- if (mono_src)
- qt_render_bitmap(d->dpy, d->scrn, pmPicture, d->picture,
- sx, sy, x, y, w, h, d->cpen);
- else
- XRenderComposite(d->dpy, d->composition_mode,
- pmPicture, XNone, d->picture,
- sx, sy, 0, 0, x, y, w, h);
- }
- } else
-#endif // QT_CONFIG(xrender)
- if (pixmap.depth() > 1 && !static_cast<QX11PlatformPixmap*>(pixmap.handle())->x11_mask) {
- XSetTile(d->dpy, d->gc, qt_x11PixmapHandle(pixmap));
- XSetFillStyle(d->dpy, d->gc, FillTiled);
- XSetTSOrigin(d->dpy, d->gc, x-sx, y-sy);
- XFillRectangle(d->dpy, d->hd, d->gc, x, y, w, h);
- XSetTSOrigin(d->dpy, d->gc, 0, 0);
- XSetFillStyle(d->dpy, d->gc, FillSolid);
- } else {
- qt_draw_tile(this, x, y, w, h, pixmap, sx, sy);
- }
-}
-
-bool QX11PaintEngine::drawCachedGlyphs(const QTransform &transform, const QTextItemInt &ti)
-{
-#if QT_CONFIG(xrender)
- Q_D(QX11PaintEngine);
- Q_ASSERT(ti.fontEngine->type() == QFontEngine::Freetype);
-
- if (!X11->use_xrender)
- return false;
-
- QFontEngineFT *ft = static_cast<QFontEngineFT *>(ti.fontEngine);
- QFontEngineFT::QGlyphSet *set = ft->loadGlyphSet(transform);
-
- if (!set || set->outline_drawing)
- return false;
-
- QFontEngine::GlyphFormat glyphFormat = QXRenderGlyphCache::glyphFormatForDepth(ft, d->pdev_depth);
-
- QXRenderGlyphCache *cache = static_cast<QXRenderGlyphCache *>(ft->glyphCache(set, glyphFormat, transform));
- if (!cache) {
- cache = new QXRenderGlyphCache(QXcbX11Info(), glyphFormat, transform);
- ft->setGlyphCache(set, cache);
- }
-
- return cache->draw(X11->getSolidFill(d->scrn, d->cpen.color()), d->picture, transform, ti);
-#else // !QT_CONFIG(xrender)
- return false;
-#endif // QT_CONFIG(xrender)
-}
-
-void QX11PaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
-{
- Q_D(QX11PaintEngine);
- const QTextItemInt &ti = static_cast<const QTextItemInt &>(textItem);
-
- switch (ti.fontEngine->type()) {
- case QFontEngine::TestFontEngine:
- case QFontEngine::Box:
- d->drawBoxTextItem(p, ti);
- break;
-#if QT_CONFIG(fontconfig)
- case QFontEngine::Freetype:
- drawFreetype(p, ti);
- break;
-#endif
- default:
- Q_ASSERT(false);
- }
-}
-
-#if QT_CONFIG(fontconfig)
-static bool path_for_glyphs(QPainterPath *path,
- const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions,
- const QFontEngineFT *ft)
-{
- bool result = true;
- *path = QPainterPath();
- path->setFillRule(Qt::WindingFill);
- ft->lockFace();
- int i = 0;
- while (i < glyphs.size()) {
- QFontEngineFT::Glyph *glyph = ft->loadGlyph(glyphs[i], QFixedPoint(), QFontEngineFT::Format_Mono);
- // #### fix case where we don't get a glyph
- if (!glyph || glyph->format != QFontEngineFT::Format_Mono) {
- result = false;
- break;
- }
-
- int n = 0;
- int h = glyph->height;
- int xp = qRound(positions[i].x);
- int yp = qRound(positions[i].y);
-
- xp += glyph->x;
- yp += -glyph->y + glyph->height;
- int pitch = ((glyph->width + 31) & ~31) >> 3;
-
- uchar *src = glyph->data;
- while (h--) {
- for (int x = 0; x < glyph->width; ++x) {
- bool set = src[x >> 3] & (0x80 >> (x & 7));
- if (set) {
- QRect r(xp + x, yp - h, 1, 1);
- while (x+1 < glyph->width && src[(x+1) >> 3] & (0x80 >> ((x+1) & 7))) {
- ++x;
- r.setRight(r.right()+1);
- }
-
- path->addRect(r);
- ++n;
- }
- }
- src += pitch;
- }
- ++i;
- }
- ft->unlockFace();
- return result;
-}
-
-void QX11PaintEngine::drawFreetype(const QPointF &p, const QTextItemInt &ti)
-{
- Q_D(QX11PaintEngine);
-
- if (!ti.glyphs.numGlyphs)
- return;
-
- if (!d->cpen.isSolid()) {
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- const bool xrenderPath = (X11->use_xrender
- && !(d->pdev->devType() == QInternal::Pixmap
- && static_cast<const QPixmap *>(d->pdev)->handle()->pixelType() == QPlatformPixmap::BitmapType));
-
- if (xrenderPath) {
- QTransform transform = d->matrix;
- transform.translate(p.x(), p.y());
-
- if (drawCachedGlyphs(transform, ti))
- return;
- }
-
- QTransform transform;
- transform.translate(p.x(), p.y());
-
- QVarLengthArray<QFixedPoint> positions;
- QVarLengthArray<glyph_t> glyphs;
- ti.fontEngine->getGlyphPositions(ti.glyphs, transform, ti.flags, glyphs, positions);
-
- if (glyphs.count() == 0)
- return;
-
- QFontEngineFT *ft = static_cast<QFontEngineFT *>(ti.fontEngine);
- QFontEngineFT::QGlyphSet *set = ft->loadGlyphSet(transform);
- QPainterPath path;
-
- if (!set || set->outline_drawing || !path_for_glyphs(&path, glyphs, positions, ft)) {
- QPaintEngine::drawTextItem(p, ti);
- return;
- }
-
- if (path.elementCount() <= 1)
- return;
-
- Q_ASSERT((path.elementCount() % 5) == 0);
- if (d->txop >= QTransform::TxScale) {
- painter()->save();
- painter()->setBrush(d->cpen.brush());
- painter()->setPen(Qt::NoPen);
- painter()->drawPath(path);
- painter()->restore();
- return;
- }
-
- const int rectcount = 256;
- XRectangle rects[rectcount];
- int num_rects = 0;
-
- QPoint delta(qRound(d->matrix.dx()), qRound(d->matrix.dy()));
- QRect clip(d->polygonClipper.boundingRect());
- for (int i=0; i < path.elementCount(); i+=5) {
- int x = qRound(path.elementAt(i).x);
- int y = qRound(path.elementAt(i).y);
- int w = qRound(path.elementAt(i+1).x) - x;
- int h = qRound(path.elementAt(i+2).y) - y;
-
- QRect rect = QRect(x + delta.x(), y + delta.y(), w, h);
- rect = rect.intersected(clip);
- if (rect.isEmpty())
- continue;
-
- rects[num_rects].x = short(rect.x());
- rects[num_rects].y = short(rect.y());
- rects[num_rects].width = ushort(rect.width());
- rects[num_rects].height = ushort(rect.height());
- ++num_rects;
- if (num_rects == rectcount) {
- XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
- num_rects = 0;
- }
- }
- if (num_rects > 0)
- XFillRectangles(d->dpy, d->hd, d->gc, rects, num_rects);
-}
-#endif // QT_CONFIG(fontconfig)
-
-#if QT_CONFIG(xrender)
-QXRenderGlyphCache::QXRenderGlyphCache(QXcbX11Info x, QFontEngine::GlyphFormat format, const QTransform &matrix)
- : QFontEngineGlyphCache(format, matrix)
- , xinfo(x)
- , gset(XNone)
-{}
-
-QXRenderGlyphCache::~QXRenderGlyphCache()
-{
- if (gset != XNone)
- XRenderFreeGlyphSet(xinfo.display(), gset);
-}
-
-bool QXRenderGlyphCache::addGlyphs(const QTextItemInt &ti,
- const QVarLengthArray<glyph_t> &glyphs,
- const QVarLengthArray<QFixedPoint> &positions)
-{
- Q_ASSERT(ti.fontEngine->type() == QFontEngine::Freetype);
-
- QFontEngineFT *ft = static_cast<QFontEngineFT *>(ti.fontEngine);
- QFontEngineFT::QGlyphSet *set = ft->loadGlyphSet(transform());
-
- XGlyphInfo xglyphinfo;
-
- for (int i = 0; i < glyphs.size(); ++i) {
- const QFixed sppx = ft->subPixelPositionForX(positions[i].x);
- const QFixedPoint spp(sppx, 0);
- QFontEngineFT::Glyph *glyph = set->getGlyph(glyphs[i], spp);
- Glyph xglyphid = qHash(QFontEngineFT::GlyphAndSubPixelPosition(glyphs[i], spp));
-
- if (glyph && glyph->format == glyphFormat()) {
- if (cachedGlyphs.contains(xglyphid)) {
- continue;
- } else {
- set->setGlyph(glyphs[i], spp, nullptr);
- delete glyph;
- glyph = 0;
- }
- }
-
- glyph = ft->loadGlyphFor(glyphs[i], spp, glyphFormat(), transform(), QColor());
-
- if (glyph == 0 || glyph->format != glyphFormat())
- return false;
-
- if (glyph->format == QFontEngine::Format_Mono) {
- // Must convert bitmap from msb to lsb bit order
- QImage img(glyph->data, glyph->width, glyph->height, QImage::Format_Mono);
- img = img.convertToFormat(QImage::Format_MonoLSB);
- memcpy(glyph->data, img.constBits(), static_cast<size_t>(img.sizeInBytes()));
- }
-
- set->setGlyph(glyphs[i], spp, glyph);
- Q_ASSERT(glyph->data || glyph->width == 0 || glyph->height == 0);
-
- xglyphinfo.width = glyph->width;
- xglyphinfo.height = glyph->height;
- xglyphinfo.x = -glyph->x;
- xglyphinfo.y = glyph->y;
- xglyphinfo.xOff = glyph->advance;
- xglyphinfo.yOff = 0;
-
- XRenderAddGlyphs(xinfo.display(), glyphSet(), &xglyphid, &xglyphinfo, 1, (const char *) glyph->data, glyphBufferSize(*glyph));
- cachedGlyphs.insert(xglyphid);
- }
-
- return true;
-}
-
-bool QXRenderGlyphCache::draw(Drawable src, Drawable dst, const QTransform &matrix, const QTextItemInt &ti)
-{
- Q_ASSERT(ti.fontEngine->type() == QFontEngine::Freetype);
-
- if (ti.glyphs.numGlyphs == 0)
- return true;
-
- QFontEngineFT *ft = static_cast<QFontEngineFT *>(ti.fontEngine);
- QFontEngineFT::QGlyphSet *set = ft->loadGlyphSet(matrix);
-
- QVarLengthArray<glyph_t> glyphs;
- QVarLengthArray<QFixedPoint> positions;
- ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
-
- if (glyphs.isEmpty())
- return true;
-
- if (!addGlyphs(ti, glyphs, positions))
- return false;
-
- QVarLengthArray<unsigned int> chars(glyphs.size());
-
- for (int i = 0; i < glyphs.size(); ++i)
- chars[i] = glyphId(glyphs[i], ft->subPixelPositionForX(positions[i].x));
-
- int i = 0;
- while (i < glyphs.size() && !isValidCoordinate(positions[i]))
- ++i;
-
- if (i >= glyphs.size())
- return true;
-
- QFixed xp = positions[i].x;
- QFixed yp = positions[i].y;
- QFixed offs = QFixed::fromReal(aliasedCoordinateDelta);
-
- XGlyphElt32 elt;
- elt.glyphset = gset;
- elt.chars = &chars[i];
- elt.nchars = 1;
- elt.xOff = qRound(xp + offs);
- elt.yOff = qRound(yp + offs);
-
- ++i;
-
- for (; i < glyphs.size(); ++i) {
- if (!isValidCoordinate(positions[i]))
- break;
-
- const QFixed sppx = ft->subPixelPositionForX(positions[i].x);
- const QFixedPoint spp(sppx, 0);
- QFontEngineFT::Glyph *g = set->getGlyph(glyphs[i], spp);
-
- if (g
- && positions[i].x == xp + g->advance
- && positions[i].y == yp
- && elt.nchars < 253 // don't draw more than 253 characters as some X servers
- // hang with it
- ) {
- elt.nchars++;
- xp += g->advance;
- } else {
- xp = positions[i].x;
- yp = positions[i].y;
-
- XRenderCompositeText32(xinfo.display(), PictOpOver, src, dst,
- renderPictFormat(), 0, 0, 0, 0,
- &elt, 1);
- elt.chars = &chars[i];
- elt.nchars = 1;
- elt.xOff = qRound(xp + offs);
- elt.yOff = qRound(yp + offs);
- }
- }
-
- XRenderCompositeText32(xinfo.display(), PictOpOver, src, dst,
- renderPictFormat(), 0, 0, 0, 0, &elt, 1);
-
- return true;
-}
-
-GlyphSet QXRenderGlyphCache::glyphSet()
-{
- if (gset == XNone)
- gset = XRenderCreateGlyphSet(xinfo.display(), renderPictFormat());
-
- Q_ASSERT(gset != XNone);
- return gset;
-}
-
-int QXRenderGlyphCache::glyphBufferSize(const QFontEngineFT::Glyph &glyph) const
-{
- int pitch = 0;
-
- switch (glyphFormat()) {
- case QFontEngine::Format_Mono:
- pitch = ((glyph.width + 31) & ~31) >> 3;
- break;
- case QFontEngine::Format_A8:
- pitch = (glyph.width + 3) & ~3;
- break;
- default:
- pitch = glyph.width * 4;
- break;
- }
-
- return pitch * glyph.height;
-}
-
-QImage::Format QXRenderGlyphCache::imageFormat() const
-{
- switch (glyphFormat()) {
- case QFontEngine::Format_None:
- Q_UNREACHABLE();
- break;
- case QFontEngine::Format_Mono:
- return QImage::Format_Mono;
- break;
- case QFontEngine::Format_A8:
- return QImage::Format_Alpha8;
- break;
- case QFontEngine::Format_A32:
- case QFontEngine::Format_ARGB:
- return QImage::Format_ARGB32_Premultiplied;
- break;
- }
-
- Q_UNREACHABLE();
-}
-
-const XRenderPictFormat *QXRenderGlyphCache::renderPictFormat() const
-{
- switch (glyphFormat()) {
- case QFontEngine::Format_None:
- Q_UNREACHABLE();
- break;
- case QFontEngine::Format_Mono:
- return XRenderFindStandardFormat(xinfo.display(), PictStandardA1);
- break;
- case QFontEngine::Format_A8:
- return XRenderFindStandardFormat(xinfo.display(), PictStandardA8);
- break;
- case QFontEngine::Format_A32:
- case QFontEngine::Format_ARGB:
- return XRenderFindStandardFormat(xinfo.display(), PictStandardARGB32);
- break;
- }
-
- Q_UNREACHABLE();
-}
-
-QFontEngine::GlyphFormat QXRenderGlyphCache::glyphFormatForDepth(QFontEngine *fontEngine, int depth)
-{
- QFontEngine::GlyphFormat glyphFormat = fontEngine->glyphFormat;
-
- if (glyphFormat == QFontEngine::Format_None) {
- switch (depth) {
- case 32:
- glyphFormat = QFontEngine::Format_ARGB;
- break;
- case 24:
- glyphFormat = QFontEngine::Format_A32;
- break;
- case 1:
- glyphFormat = QFontEngine::Format_Mono;
- break;
- default:
- glyphFormat = QFontEngine::Format_A8;
- break;
- }
- }
-
- return glyphFormat;
-}
-
-Glyph QXRenderGlyphCache::glyphId(glyph_t glyph, QFixed subPixelPosition)
-{
- return qHash(QFontEngineFT::GlyphAndSubPixelPosition(glyph, QFixedPoint(subPixelPosition, 0)));
-}
-
-bool QXRenderGlyphCache::isValidCoordinate(const QFixedPoint &fp)
-{
- enum { t_min = SHRT_MIN, t_max = SHRT_MAX };
- return (fp.x < t_min || fp.x > t_max || fp.y < t_min || fp.y > t_max) ? false : true;
-}
-#endif // QT_CONFIG(xrender)
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h
deleted file mode 100644
index bcbf84682c6..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qpaintengine_x11_p.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-#include <QtGui/QPaintEngine>
-
-typedef unsigned long XID;
-typedef XID Drawable;
-typedef struct _XGC *GC;
-
-QT_BEGIN_NAMESPACE
-
-extern "C" {
-Drawable qt_x11Handle(const QPaintDevice *pd);
-GC qt_x11_get_pen_gc(QPainter *);
-GC qt_x11_get_brush_gc(QPainter *);
-}
-
-class QX11PaintEnginePrivate;
-class QX11PaintEngine : public QPaintEngine
-{
- Q_DECLARE_PRIVATE(QX11PaintEngine)
-public:
- QX11PaintEngine();
- ~QX11PaintEngine();
-
- bool begin(QPaintDevice *pdev) override;
- bool end() override;
-
- void updateState(const QPaintEngineState &state) override;
-
- void updatePen(const QPen &pen);
- void updateBrush(const QBrush &brush, const QPointF &pt);
- void updateRenderHints(QPainter::RenderHints hints);
- void updateFont(const QFont &font);
- void updateMatrix(const QTransform &matrix);
- void updateClipRegion_dev(const QRegion &region, Qt::ClipOperation op);
-
- void drawLines(const QLine *lines, int lineCount) override;
- void drawLines(const QLineF *lines, int lineCount) override;
-
- void drawRects(const QRect *rects, int rectCount) override;
- void drawRects(const QRectF *rects, int rectCount) override;
-
- void drawPoints(const QPoint *points, int pointCount) override;
- void drawPoints(const QPointF *points, int pointCount) override;
-
- void drawEllipse(const QRect &r) override;
- void drawEllipse(const QRectF &r) override;
-
- virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) override;
- inline void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) override
- { QPaintEngine::drawPolygon(points, pointCount, mode); }
-
- void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr) override;
- void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s) override;
- void drawPath(const QPainterPath &path) override;
- void drawTextItem(const QPointF &p, const QTextItem &textItem) override;
- void drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
- Qt::ImageConversionFlags flags = Qt::AutoColor) override;
-
- virtual Drawable handle() const;
- inline Type type() const override { return QPaintEngine::X11; }
-
- QPainter::RenderHints supportedRenderHints() const;
-
-protected:
- QX11PaintEngine(QX11PaintEnginePrivate &dptr);
-
-#if QT_CONFIG(fontconfig)
- void drawFreetype(const QPointF &p, const QTextItemInt &ti);
- bool drawCachedGlyphs(const QTransform &transform, const QTextItemInt &ti);
-#endif // QT_CONFIG(fontconfig)
-
- friend class QPixmap;
- friend class QFontEngineBox;
- friend GC qt_x11_get_pen_gc(QPainter *);
- friend GC qt_x11_get_brush_gc(QPainter *);
-
-private:
- Q_DISABLE_COPY_MOVE(QX11PaintEngine)
-};
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp
deleted file mode 100644
index b47bd3f5dcc..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11.cpp
+++ /dev/null
@@ -1,2087 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#include <QGuiApplication>
-
-#include <private/qdrawhelper_p.h>
-#include <private/qimage_p.h>
-#include <private/qimagepixmapcleanuphooks_p.h>
-
-#include "qxcbnativepainting.h"
-#include "qpixmap_x11_p.h"
-#include "qcolormap_x11_p.h"
-#include "qpaintengine_x11_p.h"
-
-QT_BEGIN_NAMESPACE
-
-#if QT_POINTER_SIZE == 8 // 64-bit versions
-
-Q_ALWAYS_INLINE uint PREMUL(uint x) {
- uint a = x >> 24;
- quint64 t = (((quint64(x)) | ((quint64(x)) << 24)) & 0x00ff00ff00ff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff00ff00ff) + 0x80008000800080) >> 8;
- t &= 0x000000ff00ff00ff;
- return (uint(t)) | (uint(t >> 24)) | (a << 24);
-}
-
-#else // 32-bit versions
-
-Q_ALWAYS_INLINE uint PREMUL(uint x) {
- uint a = x >> 24;
- uint t = (x & 0xff00ff) * a;
- t = (t + ((t >> 8) & 0xff00ff) + 0x800080) >> 8;
- t &= 0xff00ff;
-
- x = ((x >> 8) & 0xff) * a;
- x = (x + ((x >> 8) & 0xff) + 0x80);
- x &= 0xff00;
- x |= t | (a << 24);
- return x;
-}
-#endif
-
-
-
-struct QXImageWrapper
-{
- XImage *xi;
-};
-
-QPixmap qt_toX11Pixmap(const QImage &image)
-{
- QPlatformPixmap *data =
- new QX11PlatformPixmap(image.depth() == 1
- ? QPlatformPixmap::BitmapType
- : QPlatformPixmap::PixmapType);
-
- data->fromImage(image, Qt::AutoColor);
-
- return QPixmap(data);
-}
-
-QPixmap qt_toX11Pixmap(const QPixmap &pixmap)
-{
- if (pixmap.isNull())
- return QPixmap();
-
- if (QPixmap(pixmap).data_ptr()->classId() == QPlatformPixmap::X11Class)
- return pixmap;
-
- return qt_toX11Pixmap(pixmap.toImage());
-}
-
-// For thread-safety:
-// image->data does not belong to X11, so we must free it ourselves.
-
-inline static void qSafeXDestroyImage(XImage *x)
-{
- if (x->data) {
- free(x->data);
- x->data = 0;
- }
- XDestroyImage(x);
-}
-
-QBitmap QX11PlatformPixmap::mask_to_bitmap(int screen) const
-{
- if (!x11_mask)
- return QBitmap();
- qt_x11SetDefaultScreen(screen);
- QBitmap bm(w, h);
- QX11PlatformPixmap *that = qt_x11Pixmap(bm);
- const QXcbX11Info *x = that->x11_info();
- GC gc = XCreateGC(x->display(), that->handle(), 0, 0);
- XCopyArea(x->display(), x11_mask, that->handle(), gc, 0, 0,
- that->width(), that->height(), 0, 0);
- XFreeGC(x->display(), gc);
- return bm;
-}
-
-void QX11PlatformPixmap::bitmapFromImage(const QImage &image)
-{
- w = image.width();
- h = image.height();
- d = 1;
- is_null = (w <= 0 || h <= 0);
- hd = createBitmapFromImage(image);
-#if QT_CONFIG(xrender)
- if (X11->use_xrender)
- picture = XRenderCreatePicture(xinfo.display(), hd,
- XRenderFindStandardFormat(xinfo.display(), PictStandardA1), 0, 0);
-#endif // QT_CONFIG(xrender)
-}
-
-bool QX11PlatformPixmap::canTakeQImageFromXImage(const QXImageWrapper &xiWrapper) const
-{
- XImage *xi = xiWrapper.xi;
-
- if (xi->format != ZPixmap)
- return false;
-
- // ARGB32_Premultiplied
- if (picture && depth() == 32)
- return true;
-
- // RGB32
- if (depth() == 24 && xi->bits_per_pixel == 32 && xi->red_mask == 0xff0000
- && xi->green_mask == 0xff00 && xi->blue_mask == 0xff)
- return true;
-
- // RGB16
- if (depth() == 16 && xi->bits_per_pixel == 16 && xi->red_mask == 0xf800
- && xi->green_mask == 0x7e0 && xi->blue_mask == 0x1f)
- return true;
-
- return false;
-}
-
-QImage QX11PlatformPixmap::takeQImageFromXImage(const QXImageWrapper &xiWrapper) const
-{
- XImage *xi = xiWrapper.xi;
-
- QImage::Format format = QImage::Format_ARGB32_Premultiplied;
- if (depth() == 24)
- format = QImage::Format_RGB32;
- else if (depth() == 16)
- format = QImage::Format_RGB16;
-
- QImage image((uchar *)xi->data, xi->width, xi->height, xi->bytes_per_line, format);
- image.setDevicePixelRatio(devicePixelRatio());
- // take ownership
- image.data_ptr()->own_data = true;
- xi->data = 0;
-
- // we may have to swap the byte order
- if ((QSysInfo::ByteOrder == QSysInfo::LittleEndian && xi->byte_order == MSBFirst)
- || (QSysInfo::ByteOrder == QSysInfo::BigEndian && xi->byte_order == LSBFirst))
- {
- for (int i=0; i < image.height(); i++) {
- if (depth() == 16) {
- ushort *p = (ushort*)image.scanLine(i);
- ushort *end = p + image.width();
- while (p < end) {
- *p = ((*p << 8) & 0xff00) | ((*p >> 8) & 0x00ff);
- p++;
- }
- } else {
- uint *p = (uint*)image.scanLine(i);
- uint *end = p + image.width();
- while (p < end) {
- *p = ((*p << 24) & 0xff000000) | ((*p << 8) & 0x00ff0000)
- | ((*p >> 8) & 0x0000ff00) | ((*p >> 24) & 0x000000ff);
- p++;
- }
- }
- }
- }
-
- // fix-up alpha channel
- if (format == QImage::Format_RGB32) {
- QRgb *p = (QRgb *)image.bits();
- for (int y = 0; y < xi->height; ++y) {
- for (int x = 0; x < xi->width; ++x)
- p[x] |= 0xff000000;
- p += xi->bytes_per_line / 4;
- }
- }
-
- XDestroyImage(xi);
- return image;
-}
-
-XID QX11PlatformPixmap::bitmap_to_mask(const QBitmap &bitmap, int screen)
-{
- if (bitmap.isNull())
- return 0;
- QBitmap bm = bitmap;
- qt_x11SetScreen(bm, screen);
-
- QX11PlatformPixmap *that = qt_x11Pixmap(bm);
- const QXcbX11Info *x = that->x11_info();
- Pixmap mask = XCreatePixmap(x->display(), RootWindow(x->display(), screen),
- that->width(), that->height(), 1);
- GC gc = XCreateGC(x->display(), mask, 0, 0);
- XCopyArea(x->display(), that->handle(), mask, gc, 0, 0,
- that->width(), that->height(), 0, 0);
- XFreeGC(x->display(), gc);
- return mask;
-}
-
-Drawable qt_x11Handle(const QPixmap &pixmap)
-{
- if (pixmap.isNull())
- return XNone;
-
- if (pixmap.handle()->classId() != QPlatformPixmap::X11Class)
- return XNone;
-
- return static_cast<const QX11PlatformPixmap *>(pixmap.handle())->handle();
-}
-
-
-/*****************************************************************************
- Internal functions
- *****************************************************************************/
-
-//extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
-
-// Returns position of highest bit set or -1 if none
-static int highest_bit(uint v)
-{
- int i;
- uint b = (uint)1 << 31;
- for (i=31; ((b & v) == 0) && i>=0; i--)
- b >>= 1;
- return i;
-}
-
-// Counts the number of bits set in 'v'
-static uint n_bits(uint v)
-{
- int i = 0;
- while (v) {
- v = v & (v - 1);
- i++;
- }
- return i;
-}
-
-static uint *red_scale_table = nullptr;
-static uint *green_scale_table = nullptr;
-static uint *blue_scale_table = nullptr;
-
-static void cleanup_scale_tables()
-{
- delete[] red_scale_table;
- delete[] green_scale_table;
- delete[] blue_scale_table;
-}
-
-/*
- Could do smart bitshifting, but the "obvious" algorithm only works for
- nBits >= 4. This is more robust.
-*/
-static void build_scale_table(uint **table, uint nBits)
-{
- if (nBits > 7) {
- qWarning("build_scale_table: internal error, nBits = %i", nBits);
- return;
- }
- if (!*table) {
- static bool firstTable = true;
- if (firstTable) {
- qAddPostRoutine(cleanup_scale_tables);
- firstTable = false;
- }
- *table = new uint[256];
- }
- int maxVal = (1 << nBits) - 1;
- int valShift = 8 - nBits;
- int i;
- for (i = 0 ; i < maxVal + 1 ; i++)
- (*table)[i << valShift] = i*255/maxVal;
-}
-
-static int defaultScreen = -1;
-
-int qt_x11SetDefaultScreen(int screen)
-{
- int old = defaultScreen;
- defaultScreen = screen;
- return old;
-}
-
-void qt_x11SetScreen(QPixmap &pixmap, int screen)
-{
- if (pixmap.paintingActive()) {
- qWarning("qt_x11SetScreen(): Cannot change screens during painting");
- return;
- }
-
- if (pixmap.isNull())
- return;
-
- if (pixmap.handle()->classId() != QPlatformPixmap::X11Class)
- return;
-
- if (screen < 0)
- screen = QXcbX11Info::appScreen();
-
- QX11PlatformPixmap *pm = static_cast<QX11PlatformPixmap *>(pixmap.handle());
- if (screen == pm->xinfo.screen())
- return; // nothing to do
-
- if (pixmap.isNull()) {
- pm->xinfo = QXcbX11Info::fromScreen(screen);
- return;
- }
-
-#if 0
- qDebug("qt_x11SetScreen for %p from %d to %d. Size is %d/%d", pm, pm->xinfo.screen(), screen, pm->width(), pm->height());
-#endif
-
- qt_x11SetDefaultScreen(screen);
- pixmap = qt_toX11Pixmap(pixmap.toImage());
-}
-
-/*****************************************************************************
- QPixmap member functions
- *****************************************************************************/
-
-QBasicAtomicInt qt_pixmap_serial = Q_BASIC_ATOMIC_INITIALIZER(0);
-int Q_GUI_EXPORT qt_x11_preferred_pixmap_depth = 0;
-
-QX11PlatformPixmap::QX11PlatformPixmap(PixelType pixelType)
- : QPlatformPixmap(pixelType, X11Class), hd(0),
- flags(Uninitialized), x11_mask(0), picture(0), mask_picture(0), hd2(0),
- dpr(1.0), pengine(0)
-{}
-
-QX11PlatformPixmap::~QX11PlatformPixmap()
-{
- // Cleanup hooks have to be called before the handles are freed
- if (is_cached) {
- QImagePixmapCleanupHooks::executePlatformPixmapDestructionHooks(this);
- is_cached = false;
- }
-
- release();
-}
-
-QPlatformPixmap *QX11PlatformPixmap::createCompatiblePlatformPixmap() const
-{
- QX11PlatformPixmap *p = new QX11PlatformPixmap(pixelType());
- p->setDevicePixelRatio(devicePixelRatio());
- return p;
-}
-
-void QX11PlatformPixmap::resize(int width, int height)
-{
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- w = width;
- h = height;
- is_null = (w <= 0 || h <= 0);
-
- if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
- xinfo = QXcbX11Info::fromScreen(defaultScreen);
- }
-
- int dd = xinfo.depth();
-
- if (qt_x11_preferred_pixmap_depth)
- dd = qt_x11_preferred_pixmap_depth;
-
- bool make_null = w <= 0 || h <= 0; // create null pixmap
- d = (pixelType() == BitmapType ? 1 : dd);
- if (make_null || d == 0) {
- w = 0;
- h = 0;
- is_null = true;
- hd = 0;
- picture = 0;
- d = 0;
- if (!make_null)
- qWarning("QPixmap: Invalid pixmap parameters");
- return;
- }
- hd = XCreatePixmap(xinfo.display(),
- RootWindow(xinfo.display(), xinfo.screen()),
- w, h, d);
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 1
- ? XRenderFindStandardFormat(xinfo.display(), PictStandardA1)
- : XRenderFindVisualFormat(xinfo.display(), (Visual *) xinfo.visual());
- picture = XRenderCreatePicture(xinfo.display(), hd, format, 0, 0);
- }
-#endif // QT_CONFIG(xrender)
-}
-
-struct QX11AlphaDetector
-{
- bool hasAlpha() const {
- if (checked)
- return has;
- // Will implicitly also check format and return quickly for opaque types...
- checked = true;
- has = image->isNull() ? false : const_cast<QImage *>(image)->data_ptr()->checkForAlphaPixels();
- return has;
- }
-
- bool hasXRenderAndAlpha() const {
- if (!X11->use_xrender)
- return false;
- return hasAlpha();
- }
-
- QX11AlphaDetector(const QImage *i, Qt::ImageConversionFlags flags)
- : image(i), checked(false), has(false)
- {
- if (flags & Qt::NoOpaqueDetection) {
- checked = true;
- has = image->hasAlphaChannel();
- }
- }
-
- const QImage *image;
- mutable bool checked;
- mutable bool has;
-};
-
-void QX11PlatformPixmap::fromImage(const QImage &img, Qt::ImageConversionFlags flags)
-{
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- w = img.width();
- h = img.height();
- d = img.depth();
- is_null = (w <= 0 || h <= 0);
- setDevicePixelRatio(img.devicePixelRatio());
-
- if (is_null) {
- w = h = 0;
- return;
- }
-
- if (defaultScreen >= 0 && defaultScreen != xinfo.screen()) {
- xinfo = QXcbX11Info::fromScreen(defaultScreen);
- }
-
- if (pixelType() == BitmapType) {
- bitmapFromImage(img);
- return;
- }
-
- if (uint(w) >= 32768 || uint(h) >= 32768) {
- w = h = 0;
- is_null = true;
- return;
- }
-
- QX11AlphaDetector alphaCheck(&img, flags);
- int dd = alphaCheck.hasXRenderAndAlpha() ? 32 : xinfo.depth();
-
- if (qt_x11_preferred_pixmap_depth)
- dd = qt_x11_preferred_pixmap_depth;
-
- QImage image = img;
-
- // must be monochrome
- if (dd == 1 || (flags & Qt::ColorMode_Mask) == Qt::MonoOnly) {
- if (d != 1) {
- // dither
- image = image.convertToFormat(QImage::Format_MonoLSB, flags);
- d = 1;
- }
- } else { // can be both
- bool conv8 = false;
- if (d > 8 && dd <= 8) { // convert to 8 bit
- if ((flags & Qt::DitherMode_Mask) == Qt::AutoDither)
- flags = (flags & ~Qt::DitherMode_Mask)
- | Qt::PreferDither;
- conv8 = true;
- } else if ((flags & Qt::ColorMode_Mask) == Qt::ColorOnly) {
- conv8 = (d == 1); // native depth wanted
- } else if (d == 1) {
- if (image.colorCount() == 2) {
- QRgb c0 = image.color(0); // Auto: convert to best
- QRgb c1 = image.color(1);
- conv8 = qMin(c0,c1) != qRgb(0,0,0) || qMax(c0,c1) != qRgb(255,255,255);
- } else {
- // eg. 1-color monochrome images (they do exist).
- conv8 = true;
- }
- }
- if (conv8) {
- image = image.convertToFormat(QImage::Format_Indexed8, flags);
- d = 8;
- }
- }
-
- if (d == 1 || image.format() > QImage::Format_ARGB32_Premultiplied) {
- QImage::Format fmt = QImage::Format_RGB32;
- if (alphaCheck.hasXRenderAndAlpha() && d > 1)
- fmt = QImage::Format_ARGB32_Premultiplied;
- image = image.convertToFormat(fmt, flags);
- fromImage(image, Qt::AutoColor);
- return;
- }
-
- Display *dpy = xinfo.display();
- Visual *visual = (Visual *)xinfo.visual();
- XImage *xi = nullptr;
- bool trucol = (visual->c_class >= TrueColor);
- size_t nbytes = image.sizeInBytes();
- uchar *newbits= nullptr;
-
-#if QT_CONFIG(xrender)
- if (alphaCheck.hasXRenderAndAlpha()) {
- const QImage &cimage = image;
-
- d = 32;
-
- if (QXcbX11Info::appDepth() != d) {
- xinfo.setDepth(d);
- }
-
- hd = XCreatePixmap(dpy, RootWindow(dpy, xinfo.screen()), w, h, d);
- picture = XRenderCreatePicture(dpy, hd,
- XRenderFindStandardFormat(dpy, PictStandardARGB32), 0, 0);
-
- xi = XCreateImage(dpy, visual, d, ZPixmap, 0, 0, w, h, 32, 0);
- Q_CHECK_PTR(xi);
- newbits = (uchar *)malloc(xi->bytes_per_line*h);
- Q_CHECK_PTR(newbits);
- xi->data = (char *)newbits;
-
- switch (cimage.format()) {
- case QImage::Format_Indexed8: {
- QList<QRgb> colorTable = cimage.colorTable();
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const uchar *p = cimage.scanLine(y);
- for (int x = 0; x < w; ++x) {
- const QRgb rgb = colorTable[p[x]];
- const int a = qAlpha(rgb);
- if (a == 0xff)
- *xidata = rgb;
- else
- // RENDER expects premultiplied alpha
- *xidata = qRgba(qt_div_255(qRed(rgb) * a),
- qt_div_255(qGreen(rgb) * a),
- qt_div_255(qBlue(rgb) * a),
- a);
- ++xidata;
- }
- }
- }
- break;
- case QImage::Format_RGB32: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- for (int x = 0; x < w; ++x)
- *xidata++ = p[x] | 0xff000000;
- }
- }
- break;
- case QImage::Format_ARGB32: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- for (int x = 0; x < w; ++x) {
- const QRgb rgb = p[x];
- const int a = qAlpha(rgb);
- if (a == 0xff)
- *xidata = rgb;
- else
- // RENDER expects premultiplied alpha
- *xidata = qRgba(qt_div_255(qRed(rgb) * a),
- qt_div_255(qGreen(rgb) * a),
- qt_div_255(qBlue(rgb) * a),
- a);
- ++xidata;
- }
- }
-
- }
- break;
- case QImage::Format_ARGB32_Premultiplied: {
- uint *xidata = (uint *)xi->data;
- for (int y = 0; y < h; ++y) {
- const QRgb *p = (const QRgb *) cimage.scanLine(y);
- memcpy(xidata, p, w*sizeof(QRgb));
- xidata += w;
- }
- }
- break;
- default:
- Q_ASSERT(false);
- }
-
- if ((xi->byte_order == MSBFirst) != (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
- uint *xidata = (uint *)xi->data;
- uint *xiend = xidata + w*h;
- while (xidata < xiend) {
- *xidata = (*xidata >> 24)
- | ((*xidata >> 8) & 0xff00)
- | ((*xidata << 8) & 0xff0000)
- | (*xidata << 24);
- ++xidata;
- }
- }
-
- GC gc = XCreateGC(dpy, hd, 0, 0);
- XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
- XFreeGC(dpy, gc);
-
- qSafeXDestroyImage(xi);
-
- return;
- }
-#endif // QT_CONFIG(xrender)
-
- if (trucol) { // truecolor display
- if (image.format() == QImage::Format_ARGB32_Premultiplied)
- image = image.convertToFormat(QImage::Format_ARGB32);
-
- const QImage &cimage = image;
- QRgb pix[256]; // pixel translation table
- const bool d8 = (d == 8);
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit(red_mask) - 7;
- const int green_shift = highest_bit(green_mask) - 7;
- const int blue_shift = highest_bit(blue_mask) - 7;
- const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
- const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
- const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
-
- if (d8) { // setup pixel translation
- QList<QRgb> ctable = cimage.colorTable();
- for (int i=0; i < cimage.colorCount(); i++) {
- int r = qRed (ctable[i]);
- int g = qGreen(ctable[i]);
- int b = qBlue (ctable[i]);
- r = red_shift > 0 ? r << red_shift : r >> -red_shift;
- g = green_shift > 0 ? g << green_shift : g >> -green_shift;
- b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
- pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
- | ~(blue_mask | green_mask | red_mask);
- }
- }
-
- xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
- Q_CHECK_PTR(xi);
- newbits = (uchar *)malloc(xi->bytes_per_line*h);
- Q_CHECK_PTR(newbits);
- if (!newbits) // no memory
- return;
- int bppc = xi->bits_per_pixel;
-
- bool contig_bits = n_bits(red_mask) == rbits &&
- n_bits(green_mask) == gbits &&
- n_bits(blue_mask) == bbits;
- bool dither_tc =
- // Want it?
- (flags & Qt::Dither_Mask) != Qt::ThresholdDither &&
- (flags & Qt::DitherMode_Mask) != Qt::AvoidDither &&
- // Need it?
- bppc < 24 && !d8 &&
- // Can do it? (Contiguous bits?)
- contig_bits;
-
- static bool init=false;
- static int D[16][16];
- if (dither_tc && !init) {
- // I also contributed this code to XV - WWA.
- /*
- The dither matrix, D, is obtained with this formula:
-
- D2 = [0 2]
- [3 1]
-
-
- D2*n = [4*Dn 4*Dn+2*Un]
- [4*Dn+3*Un 4*Dn+1*Un]
- */
- int n,i,j;
- init=1;
-
- /* Set D2 */
- D[0][0]=0;
- D[1][0]=2;
- D[0][1]=3;
- D[1][1]=1;
-
- /* Expand using recursive definition given above */
- for (n=2; n<16; n*=2) {
- for (i=0; i<n; i++) {
- for (j=0; j<n; j++) {
- D[i][j]*=4;
- D[i+n][j]=D[i][j]+2;
- D[i][j+n]=D[i][j]+3;
- D[i+n][j+n]=D[i][j]+1;
- }
- }
- }
- init=true;
- }
-
- enum { BPP8,
- BPP16_565, BPP16_555,
- BPP16_MSB, BPP16_LSB,
- BPP24_888,
- BPP24_MSB, BPP24_LSB,
- BPP32_8888,
- BPP32_MSB, BPP32_LSB
- } mode = BPP8;
-
- bool same_msb_lsb = (xi->byte_order == MSBFirst) == (QSysInfo::ByteOrder == QSysInfo::BigEndian);
-
- if (bppc == 8) // 8 bit
- mode = BPP8;
- else if (bppc == 16) { // 16 bit MSB/LSB
- if (red_shift == 8 && green_shift == 3 && blue_shift == -3 && !d8 && same_msb_lsb)
- mode = BPP16_565;
- else if (red_shift == 7 && green_shift == 2 && blue_shift == -3 && !d8 && same_msb_lsb)
- mode = BPP16_555;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP16_LSB : BPP16_MSB;
- } else if (bppc == 24) { // 24 bit MSB/LSB
- if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
- mode = BPP24_888;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP24_LSB : BPP24_MSB;
- } else if (bppc == 32) { // 32 bit MSB/LSB
- if (red_shift == 16 && green_shift == 8 && blue_shift == 0 && !d8 && same_msb_lsb)
- mode = BPP32_8888;
- else
- mode = (xi->byte_order == LSBFirst) ? BPP32_LSB : BPP32_MSB;
- } else
- qFatal("Logic error 3");
-
-#define GET_PIXEL \
- uint pixel; \
- if (d8) pixel = pix[*src++]; \
- else { \
- int r = qRed (*p); \
- int g = qGreen(*p); \
- int b = qBlue (*p++); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask) \
- | ~(blue_mask | green_mask | red_mask); \
- }
-
-#define GET_PIXEL_DITHER_TC \
- int r = qRed (*p); \
- int g = qGreen(*p); \
- int b = qBlue (*p++); \
- const int thres = D[x%16][y%16]; \
- if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- r = red_shift > 0 \
- ? r << red_shift : r >> -red_shift; \
- g = green_shift > 0 \
- ? g << green_shift : g >> -green_shift; \
- b = blue_shift > 0 \
- ? b << blue_shift : b >> -blue_shift; \
- uint pixel = (r & red_mask)|(g & green_mask) | (b & blue_mask);
-
-// again, optimized case
-// can't be optimized that much :(
-#define GET_PIXEL_DITHER_TC_OPT(red_shift,green_shift,blue_shift,red_mask,green_mask,blue_mask, \
- rbits,gbits,bbits) \
- const int thres = D[x%16][y%16]; \
- int r = qRed (*p); \
- if (r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
- > thres) \
- r += (1<<(8-rbits)); \
- int g = qGreen(*p); \
- if (g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
- > thres) \
- g += (1<<(8-gbits)); \
- int b = qBlue (*p++); \
- if (b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
- > thres) \
- b += (1<<(8-bbits)); \
- uint pixel = ((r red_shift) & red_mask) \
- | ((g green_shift) & green_mask) \
- | ((b blue_shift) & blue_mask);
-
-#define CYCLE(body) \
- for (int y=0; y<h; y++) { \
- const uchar* src = cimage.scanLine(y); \
- uchar* dst = newbits + xi->bytes_per_line*y; \
- const QRgb* p = (const QRgb *)src; \
- body \
- }
-
- if (dither_tc) {
- switch (mode) {
- case BPP16_565:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC_OPT(<<8,<<3,>>3,0xf800,0x7e0,0x1f,5,6,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_555:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC_OPT(<<7,<<2,>>3,0x7c00,0x3e0,0x1f,5,5,5)
- *dst16++ = pixel;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL_DITHER_TC
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- default:
- qFatal("Logic error");
- }
- } else {
- switch (mode) {
- case BPP8: // 8 bit
- CYCLE(
- Q_UNUSED(p);
- for (int x=0; x<w; x++)
- *dst++ = pix[*src++];
- )
- break;
- case BPP16_565:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x = 0; x < w; x++) {
- *dst16++ = ((*p >> 8) & 0xf800)
- | ((*p >> 5) & 0x7e0)
- | ((*p >> 3) & 0x1f);
- ++p;
- }
- )
- break;
- case BPP16_555:
- CYCLE(
- quint16* dst16 = (quint16*)dst;
- for (int x=0; x<w; x++) {
- *dst16++ = ((*p >> 9) & 0x7c00)
- | ((*p >> 6) & 0x3e0)
- | ((*p >> 3) & 0x1f);
- ++p;
- }
- )
- break;
- case BPP16_MSB: // 16 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = (pixel >> 8);
- *dst++ = pixel;
- }
- )
- break;
- case BPP16_LSB: // 16 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- }
- )
- break;
- case BPP24_888:
- CYCLE(
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- for (int x=0; x<w; x++) {
- *dst++ = qRed (*p);
- *dst++ = qGreen(*p);
- *dst++ = qBlue (*p++);
- }
- } else {
- for (int x=0; x<w; x++) {
- *dst++ = qBlue (*p);
- *dst++ = qGreen(*p);
- *dst++ = qRed (*p++);
- }
- }
- )
- break;
- case BPP24_MSB: // 24 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case BPP24_LSB: // 24 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- }
- )
- break;
- case BPP32_8888:
- CYCLE(
- memcpy(dst, p, w * 4);
- )
- break;
- case BPP32_MSB: // 32 bit MSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel >> 24;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 8;
- *dst++ = pixel;
- }
- )
- break;
- case BPP32_LSB: // 32 bit LSB
- CYCLE(
- for (int x=0; x<w; x++) {
- GET_PIXEL
- *dst++ = pixel;
- *dst++ = pixel >> 8;
- *dst++ = pixel >> 16;
- *dst++ = pixel >> 24;
- }
- )
- break;
- default:
- qFatal("Logic error 2");
- }
- }
- xi->data = (char *)newbits;
- }
-
- if (d == 8 && !trucol) { // 8 bit pixmap
- int pop[256]; // pixel popularity
-
- if (image.colorCount() == 0)
- image.setColorCount(1);
-
- const QImage &cimage = image;
- memset(pop, 0, sizeof(int)*256); // reset popularity array
- for (int i = 0; i < h; i++) { // for each scanline...
- const uchar* p = cimage.scanLine(i);
- const uchar *end = p + w;
- while (p < end) // compute popularity
- pop[*p++]++;
- }
-
- newbits = (uchar *)malloc(nbytes); // copy image into newbits
- Q_CHECK_PTR(newbits);
- if (!newbits) // no memory
- return;
- uchar* p = newbits;
- memcpy(p, cimage.bits(), nbytes); // copy image data into newbits
-
- /*
- * The code below picks the most important colors. It is based on the
- * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
- */
-
- struct PIX { // pixel sort element
- uchar r,g,b,n; // color + pad
- int use; // popularity
- int index; // index in colormap
- int mindist;
- };
- int ncols = 0;
- for (int i=0; i< cimage.colorCount(); i++) { // compute number of colors
- if (pop[i] > 0)
- ncols++;
- }
- for (int i = cimage.colorCount(); i < 256; i++) // ignore out-of-range pixels
- pop[i] = 0;
-
- // works since we make sure above to have at least
- // one color in the image
- if (ncols == 0)
- ncols = 1;
-
- PIX pixarr[256]; // pixel array
- PIX pixarr_sorted[256]; // pixel array (sorted)
- memset(pixarr, 0, ncols*sizeof(PIX));
- PIX *px = &pixarr[0];
- int maxpop = 0;
- int maxpix = 0;
- uint j = 0;
- QList<QRgb> ctable = cimage.colorTable();
- for (int i = 0; i < 256; i++) { // init pixel array
- if (pop[i] > 0) {
- px->r = qRed (ctable[i]);
- px->g = qGreen(ctable[i]);
- px->b = qBlue (ctable[i]);
- px->n = 0;
- px->use = pop[i];
- if (pop[i] > maxpop) { // select most popular entry
- maxpop = pop[i];
- maxpix = j;
- }
- px->index = i;
- px->mindist = 1000000;
- px++;
- j++;
- }
- }
- pixarr_sorted[0] = pixarr[maxpix];
- pixarr[maxpix].use = 0;
-
- for (int i = 1; i < ncols; i++) { // sort pixels
- int minpix = -1, mindist = -1;
- px = &pixarr_sorted[i-1];
- int r = px->r;
- int g = px->g;
- int b = px->b;
- int dist;
- if ((i & 1) || i<10) { // sort on max distance
- for (int j=0; j<ncols; j++) {
- px = &pixarr[j];
- if (px->use) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if (px->mindist > dist)
- px->mindist = dist;
- if (px->mindist > mindist) {
- mindist = px->mindist;
- minpix = j;
- }
- }
- }
- } else { // sort on max popularity
- for (int j=0; j<ncols; j++) {
- px = &pixarr[j];
- if (px->use) {
- dist = (px->r - r)*(px->r - r) +
- (px->g - g)*(px->g - g) +
- (px->b - b)*(px->b - b);
- if (px->mindist > dist)
- px->mindist = dist;
- if (px->use > mindist) {
- mindist = px->use;
- minpix = j;
- }
- }
- }
- }
- pixarr_sorted[i] = pixarr[minpix];
- pixarr[minpix].use = 0;
- }
-
- QXcbColormap cmap = QXcbColormap::instance(xinfo.screen());
- uint pix[256]; // pixel translation table
- px = &pixarr_sorted[0];
- for (int i = 0; i < ncols; i++) { // allocate colors
- QColor c(px->r, px->g, px->b);
- pix[px->index] = cmap.pixel(c);
- px++;
- }
-
- p = newbits;
- for (size_t i = 0; i < nbytes; i++) { // translate pixels
- *p = pix[*p];
- p++;
- }
- }
-
- if (!xi) { // X image not created
- xi = XCreateImage(dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0);
- if (xi->bits_per_pixel == 16) { // convert 8 bpp ==> 16 bpp
- ushort *p2;
- int p2inc = xi->bytes_per_line/sizeof(ushort);
- ushort *newerbits = (ushort *)malloc(xi->bytes_per_line * h);
- Q_CHECK_PTR(newerbits);
- if (!newerbits) // no memory
- return;
- uchar* p = newbits;
- for (int y = 0; y < h; y++) { // OOPS: Do right byte order!!
- p2 = newerbits + p2inc*y;
- for (int x = 0; x < w; x++)
- *p2++ = *p++;
- }
- free(newbits);
- newbits = (uchar *)newerbits;
- } else if (xi->bits_per_pixel != 8) {
- qWarning("QPixmap::fromImage: Display not supported "
- "(bpp=%d)", xi->bits_per_pixel);
- }
- xi->data = (char *)newbits;
- }
-
- hd = XCreatePixmap(dpy,
- RootWindow(dpy, xinfo.screen()),
- w, h, dd);
-
- GC gc = XCreateGC(dpy, hd, 0, 0);
- XPutImage(dpy, hd, gc, xi, 0, 0, 0, 0, w, h);
- XFreeGC(dpy, gc);
-
- qSafeXDestroyImage(xi);
- d = dd;
-
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 1
- ? XRenderFindStandardFormat(dpy, PictStandardA1)
- : XRenderFindVisualFormat(dpy, (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(dpy, hd, format, 0, 0);
- }
-#endif
-
- if (alphaCheck.hasAlpha()) {
- QBitmap m = QBitmap::fromImage(image.createAlphaMask(flags));
- setMask(m);
- }
-}
-
-void QX11PlatformPixmap::copy(const QPlatformPixmap *data, const QRect &rect)
-{
- if (data->pixelType() == BitmapType) {
- fromImage(data->toImage().copy(rect), Qt::AutoColor);
- return;
- }
-
- const QX11PlatformPixmap *x11Data = static_cast<const QX11PlatformPixmap*>(data);
-
- setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
- flags &= ~Uninitialized;
- xinfo = x11Data->xinfo;
- d = x11Data->d;
- w = rect.width();
- h = rect.height();
- is_null = (w <= 0 || h <= 0);
- hd = XCreatePixmap(xinfo.display(),
- RootWindow(xinfo.display(), x11Data->xinfo.screen()),
- w, h, d);
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- XRenderPictFormat *format = d == 32
- ? XRenderFindStandardFormat(xinfo.display(), PictStandardARGB32)
- : XRenderFindVisualFormat(xinfo.display(), (Visual *)xinfo.visual());
- picture = XRenderCreatePicture(xinfo.display(), hd, format, 0, 0);
- }
-#endif // QT_CONFIG(xrender)
- if (x11Data->x11_mask) {
- x11_mask = XCreatePixmap(xinfo.display(), hd, w, h, 1);
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- mask_picture = XRenderCreatePicture(xinfo.display(), x11_mask,
- XRenderFindStandardFormat(xinfo.display(), PictStandardA1), 0, 0);
- XRenderPictureAttributes attrs;
- attrs.alpha_map = x11Data->mask_picture;
- XRenderChangePicture(xinfo.display(), x11Data->picture, CPAlphaMap, &attrs);
- }
-#endif
- }
-
-#if QT_CONFIG(xrender)
- if (x11Data->picture && x11Data->d == 32) {
- XRenderComposite(xinfo.display(), PictOpSrc,
- x11Data->picture, 0, picture,
- rect.x(), rect.y(), 0, 0, 0, 0, w, h);
- } else
-#endif
- {
- GC gc = XCreateGC(xinfo.display(), hd, 0, 0);
- XCopyArea(xinfo.display(), x11Data->hd, hd, gc,
- rect.x(), rect.y(), w, h, 0, 0);
- if (x11Data->x11_mask) {
- GC monogc = XCreateGC(xinfo.display(), x11_mask, 0, 0);
- XCopyArea(xinfo.display(), x11Data->x11_mask, x11_mask, monogc,
- rect.x(), rect.y(), w, h, 0, 0);
- XFreeGC(xinfo.display(), monogc);
- }
- XFreeGC(xinfo.display(), gc);
- }
-}
-
-bool QX11PlatformPixmap::scroll(int dx, int dy, const QRect &rect)
-{
- GC gc = XCreateGC(xinfo.display(), hd, 0, 0);
- XCopyArea(xinfo.display(), hd, hd, gc,
- rect.left(), rect.top(), rect.width(), rect.height(),
- rect.left() + dx, rect.top() + dy);
- XFreeGC(xinfo.display(), gc);
- return true;
-}
-
-int QX11PlatformPixmap::metric(QPaintDevice::PaintDeviceMetric metric) const
-{
- switch (metric) {
- case QPaintDevice::PdmDevicePixelRatio:
- return devicePixelRatio();
- break;
- case QPaintDevice::PdmDevicePixelRatioScaled:
- return devicePixelRatio() * QPaintDevice::devicePixelRatioFScale();
- break;
- case QPaintDevice::PdmWidth:
- return w;
- case QPaintDevice::PdmHeight:
- return h;
- case QPaintDevice::PdmNumColors:
- return 1 << d;
- case QPaintDevice::PdmDepth:
- return d;
- case QPaintDevice::PdmWidthMM: {
- const int screen = xinfo.screen();
- const int mm = DisplayWidthMM(xinfo.display(), screen) * w
- / DisplayWidth(xinfo.display(), screen);
- return mm;
- }
- case QPaintDevice::PdmHeightMM: {
- const int screen = xinfo.screen();
- const int mm = (DisplayHeightMM(xinfo.display(), screen) * h)
- / DisplayHeight(xinfo.display(), screen);
- return mm;
- }
- case QPaintDevice::PdmDpiX:
- case QPaintDevice::PdmPhysicalDpiX:
- return QXcbX11Info::appDpiX(xinfo.screen());
- case QPaintDevice::PdmDpiY:
- case QPaintDevice::PdmPhysicalDpiY:
- return QXcbX11Info::appDpiY(xinfo.screen());
- default:
- qWarning("QX11PlatformPixmap::metric(): Invalid metric");
- return 0;
- }
-}
-
-void QX11PlatformPixmap::fill(const QColor &fillColor)
-{
- if (fillColor.alpha() != 255) {
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- if (!picture || d != 32)
- convertToARGB32(/*preserveContents = */false);
-
- ::Picture src = X11->getSolidFill(xinfo.screen(), fillColor);
- XRenderComposite(xinfo.display(), PictOpSrc, src, 0, picture,
- 0, 0, width(), height(),
- 0, 0, width(), height());
- } else
-#endif
- {
- QImage im(width(), height(), QImage::Format_ARGB32_Premultiplied);
- im.fill(PREMUL(fillColor.rgba()));
- release();
- fromImage(im, Qt::AutoColor | Qt::OrderedAlphaDither);
- }
- return;
- }
-
- GC gc = XCreateGC(xinfo.display(), hd, 0, 0);
- if (depth() == 1) {
- XSetForeground(xinfo.display(), gc, qGray(fillColor.rgb()) > 127 ? 0 : 1);
- } else if (X11->use_xrender && d >= 24) {
- XSetForeground(xinfo.display(), gc, fillColor.rgba());
- } else {
- XSetForeground(xinfo.display(), gc,
- QXcbColormap::instance(xinfo.screen()).pixel(fillColor));
- }
- XFillRectangle(xinfo.display(), hd, gc, 0, 0, width(), height());
- XFreeGC(xinfo.display(), gc);
-}
-
-QBitmap QX11PlatformPixmap::mask() const
-{
- QBitmap mask;
-#if QT_CONFIG(xrender)
- if (picture && d == 32) {
- // #### slow - there must be a better way..
- mask = QBitmap::fromImage(toImage().createAlphaMask());
- } else
-#endif
- if (d == 1) {
- QX11PlatformPixmap *that = const_cast<QX11PlatformPixmap*>(this);
- mask = QBitmap::fromPixmap(QPixmap(that));
- } else {
- mask = mask_to_bitmap(xinfo.screen());
- }
- return mask;
-}
-
-void QX11PlatformPixmap::setMask(const QBitmap &newmask)
-{
- if (newmask.isNull()) { // clear mask
-#if QT_CONFIG(xrender)
- if (picture && d == 32) {
- QX11PlatformPixmap newData(pixelType());
- newData.resize(w, h);
- newData.fill(Qt::black);
- XRenderComposite(xinfo.display(), PictOpOver,
- picture, 0, newData.picture,
- 0, 0, 0, 0, 0, 0, w, h);
- release();
- *this = newData;
- // the new QX11PlatformPixmap object isn't referenced yet, so
- // ref it
- ref.ref();
-
- // the below is to make sure the QX11PlatformPixmap destructor
- // doesn't delete our newly created render picture
- newData.hd = 0;
- newData.x11_mask = 0;
- newData.picture = 0;
- newData.mask_picture = 0;
- newData.hd2 = 0;
- } else
-#endif
- if (x11_mask) {
-#if QT_CONFIG(xrender)
- if (picture) {
- XRenderPictureAttributes attrs;
- attrs.alpha_map = 0;
- XRenderChangePicture(xinfo.display(), picture, CPAlphaMap,
- &attrs);
- }
- if (mask_picture)
- XRenderFreePicture(xinfo.display(), mask_picture);
- mask_picture = 0;
-#endif
- XFreePixmap(xinfo.display(), x11_mask);
- x11_mask = 0;
- }
- return;
- }
-
-#if QT_CONFIG(xrender)
- if (picture && d == 32) {
- XRenderComposite(xinfo.display(), PictOpSrc,
- picture, qt_x11Pixmap(newmask)->x11PictureHandle(),
- picture, 0, 0, 0, 0, 0, 0, w, h);
- } else
-#endif
- if (depth() == 1) {
- XGCValues vals;
- vals.function = GXand;
- GC gc = XCreateGC(xinfo.display(), hd, GCFunction, &vals);
- XCopyArea(xinfo.display(), qt_x11Pixmap(newmask)->handle(), hd, gc, 0, 0,
- width(), height(), 0, 0);
- XFreeGC(xinfo.display(), gc);
- } else {
- // ##### should or the masks together
- if (x11_mask) {
- XFreePixmap(xinfo.display(), x11_mask);
-#if QT_CONFIG(xrender)
- if (mask_picture)
- XRenderFreePicture(xinfo.display(), mask_picture);
-#endif
- }
- x11_mask = QX11PlatformPixmap::bitmap_to_mask(newmask, xinfo.screen());
-#if QT_CONFIG(xrender)
- if (picture) {
- mask_picture = XRenderCreatePicture(xinfo.display(), x11_mask,
- XRenderFindStandardFormat(xinfo.display(), PictStandardA1), 0, 0);
- XRenderPictureAttributes attrs;
- attrs.alpha_map = mask_picture;
- XRenderChangePicture(xinfo.display(), picture, CPAlphaMap, &attrs);
- }
-#endif
- }
-}
-
-bool QX11PlatformPixmap::hasAlphaChannel() const
-{
- if (picture && d == 32)
- return true;
-
- if (x11_mask && d == 1)
- return true;
-
- return false;
-}
-
-QPixmap QX11PlatformPixmap::transformed(const QTransform &transform, Qt::TransformationMode mode) const
-{
- if (mode == Qt::SmoothTransformation || transform.type() >= QTransform::TxProject) {
- QImage image = toImage();
- return QPixmap::fromImage(image.transformed(transform, mode));
- }
-
- uint w = 0;
- uint h = 0; // size of target pixmap
- uint ws, hs; // size of source pixmap
- uchar *dptr; // data in target pixmap
- uint dbpl, dbytes; // bytes per line/bytes total
- uchar *sptr; // data in original pixmap
- int sbpl; // bytes per line in original
- int bpp; // bits per pixel
- bool depth1 = depth() == 1;
- Display *dpy = xinfo.display();
-
- ws = width();
- hs = height();
-
- QTransform mat(transform.m11(), transform.m12(), transform.m13(),
- transform.m21(), transform.m22(), transform.m23(),
- 0., 0., 1);
- bool complex_xform = false;
-
- if (mat.type() <= QTransform::TxScale) {
- h = qRound(qAbs(mat.m22()) * hs);
- w = qRound(qAbs(mat.m11()) * ws);
- } else { // rotation or shearing
- QPolygonF a(QRectF(0, 0, ws, hs));
- a = mat.map(a);
- QRect r = a.boundingRect().toAlignedRect();
- w = r.width();
- h = r.height();
- complex_xform = true;
- }
- mat = QPixmap::trueMatrix(mat, ws, hs); // true matrix
-
- bool invertible;
- mat = mat.inverted(&invertible); // invert matrix
-
- if (h == 0 || w == 0 || !invertible
- || qAbs(h) >= 32768 || qAbs(w) >= 32768 )
- // error, return null pixmap
- return QPixmap();
-
- XImage *xi = XGetImage(xinfo.display(), handle(), 0, 0, ws, hs, AllPlanes,
- depth1 ? XYPixmap : ZPixmap);
-
- if (!xi)
- return QPixmap();
-
- sbpl = xi->bytes_per_line;
- sptr = (uchar *)xi->data;
- bpp = xi->bits_per_pixel;
-
- if (depth1)
- dbpl = (w+7)/8;
- else
- dbpl = ((w*bpp+31)/32)*4;
- dbytes = dbpl*h;
-
- dptr = (uchar *)malloc(dbytes); // create buffer for bits
- Q_CHECK_PTR(dptr);
- if (depth1) // fill with zeros
- memset(dptr, 0, dbytes);
- else if (bpp == 8) // fill with background color
- memset(dptr, WhitePixel(xinfo.display(), xinfo.screen()), dbytes);
- else
- memset(dptr, 0, dbytes);
-
- // #define QT_DEBUG_XIMAGE
-#if defined(QT_DEBUG_XIMAGE)
- qDebug("----IMAGE--INFO--------------");
- qDebug("width............. %d", xi->width);
- qDebug("height............ %d", xi->height);
- qDebug("xoffset........... %d", xi->xoffset);
- qDebug("format............ %d", xi->format);
- qDebug("byte order........ %d", xi->byte_order);
- qDebug("bitmap unit....... %d", xi->bitmap_unit);
- qDebug("bitmap bit order.. %d", xi->bitmap_bit_order);
- qDebug("depth............. %d", xi->depth);
- qDebug("bytes per line.... %d", xi->bytes_per_line);
- qDebug("bits per pixel.... %d", xi->bits_per_pixel);
-#endif
-
- int type;
- if (xi->bitmap_bit_order == MSBFirst)
- type = QT_XFORM_TYPE_MSBFIRST;
- else
- type = QT_XFORM_TYPE_LSBFIRST;
- int xbpl, p_inc;
- if (depth1) {
- xbpl = (w+7)/8;
- p_inc = dbpl - xbpl;
- } else {
- xbpl = (w*bpp)/8;
- p_inc = dbpl - xbpl;
- }
-
- if (!qt_xForm_helper(mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs)){
- qWarning("QPixmap::transform: display not supported (bpp=%d)",bpp);
- QPixmap pm;
- free(dptr);
- return pm;
- }
-
- qSafeXDestroyImage(xi);
-
- if (depth1) { // mono bitmap
- QBitmap bm = QBitmap::fromData(QSize(w, h), dptr,
- BitmapBitOrder(xinfo.display()) == MSBFirst
- ? QImage::Format_Mono
- : QImage::Format_MonoLSB);
- free(dptr);
- return bm;
- } else { // color pixmap
- QX11PlatformPixmap *x11Data = new QX11PlatformPixmap(QPlatformPixmap::PixmapType);
- QPixmap pm(x11Data);
- x11Data->flags &= ~QX11PlatformPixmap::Uninitialized;
- x11Data->xinfo = xinfo;
- x11Data->d = d;
- x11Data->w = w;
- x11Data->h = h;
- x11Data->is_null = (w <= 0 || h <= 0);
- x11Data->hd = XCreatePixmap(xinfo.display(),
- RootWindow(xinfo.display(), xinfo.screen()),
- w, h, d);
- x11Data->setSerialNumber(qt_pixmap_serial.fetchAndAddRelaxed(1));
-
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- XRenderPictFormat *format = x11Data->d == 32
- ? XRenderFindStandardFormat(xinfo.display(), PictStandardARGB32)
- : XRenderFindVisualFormat(xinfo.display(), (Visual *) x11Data->xinfo.visual());
- x11Data->picture = XRenderCreatePicture(xinfo.display(), x11Data->hd, format, 0, 0);
- }
-#endif // QT_CONFIG(xrender)
-
- GC gc = XCreateGC(xinfo.display(), x11Data->hd, 0, 0);
- xi = XCreateImage(dpy, (Visual*)x11Data->xinfo.visual(),
- x11Data->d,
- ZPixmap, 0, (char *)dptr, w, h, 32, 0);
- XPutImage(dpy, qt_x11Pixmap(pm)->handle(), gc, xi, 0, 0, 0, 0, w, h);
- qSafeXDestroyImage(xi);
- XFreeGC(xinfo.display(), gc);
-
- if (x11_mask) { // xform mask, too
- pm.setMask(mask_to_bitmap(xinfo.screen()).transformed(transform));
- } else if (d != 32 && complex_xform) { // need a mask!
- QBitmap mask(ws, hs);
- mask.fill(Qt::color1);
- pm.setMask(mask.transformed(transform));
- }
- return pm;
- }
-}
-
-QImage QX11PlatformPixmap::toImage() const
-{
- return toImage(QRect(0, 0, w, h));
-}
-
-QImage QX11PlatformPixmap::toImage(const QRect &rect) const
-{
- Window root_return;
- int x_return;
- int y_return;
- unsigned int width_return;
- unsigned int height_return;
- unsigned int border_width_return;
- unsigned int depth_return;
-
- XGetGeometry(xinfo.display(), hd, &root_return, &x_return, &y_return, &width_return, &height_return, &border_width_return, &depth_return);
-
- QXImageWrapper xiWrapper;
- xiWrapper.xi = XGetImage(xinfo.display(), hd, rect.x(), rect.y(), rect.width(), rect.height(),
- AllPlanes, (depth() == 1) ? XYPixmap : ZPixmap);
-
- Q_CHECK_PTR(xiWrapper.xi);
- if (!xiWrapper.xi)
- return QImage();
-
- if (!x11_mask && canTakeQImageFromXImage(xiWrapper))
- return takeQImageFromXImage(xiWrapper);
-
- QImage image = toImage(xiWrapper, rect);
- qSafeXDestroyImage(xiWrapper.xi);
- return image;
-}
-
-#if QT_CONFIG(xrender)
-static XRenderPictFormat *qt_renderformat_for_depth(const QXcbX11Info &xinfo, int depth)
-{
- if (depth == 1)
- return XRenderFindStandardFormat(xinfo.display(), PictStandardA1);
- else if (depth == 32)
- return XRenderFindStandardFormat(xinfo.display(), PictStandardARGB32);
- else
- return XRenderFindVisualFormat(xinfo.display(), (Visual *)xinfo.visual());
-}
-#endif
-
-Q_GLOBAL_STATIC(QX11PaintEngine, qt_x11_paintengine)
-
-QPaintEngine *QX11PlatformPixmap::paintEngine() const
-{
- QX11PlatformPixmap *that = const_cast<QX11PlatformPixmap*>(this);
-
- if ((flags & Readonly)/* && share_mode == QPixmap::ImplicitlyShared*/) {
- // if someone wants to draw onto us, copy the shared contents
- // and turn it into a fully fledged QPixmap
- ::Pixmap hd_copy = XCreatePixmap(xinfo.display(), RootWindow(xinfo.display(), xinfo.screen()),
- w, h, d);
-#if QT_CONFIG(xrender)
- if (picture && d == 32) {
- XRenderPictFormat *format = qt_renderformat_for_depth(xinfo, d);
- ::Picture picture_copy = XRenderCreatePicture(xinfo.display(),
- hd_copy, format,
- 0, 0);
-
- XRenderComposite(xinfo.display(), PictOpSrc, picture, 0, picture_copy,
- 0, 0, 0, 0, 0, 0, w, h);
- XRenderFreePicture(xinfo.display(), picture);
- that->picture = picture_copy;
- } else
-#endif
- {
- GC gc = XCreateGC(xinfo.display(), hd_copy, 0, 0);
- XCopyArea(xinfo.display(), hd, hd_copy, gc, 0, 0, w, h, 0, 0);
- XFreeGC(xinfo.display(), gc);
- }
- that->hd = hd_copy;
- that->flags &= ~QX11PlatformPixmap::Readonly;
- }
-
- if (qt_x11_paintengine->isActive()) {
- if (!that->pengine)
- that->pengine = new QX11PaintEngine;
-
- return that->pengine;
- }
-
- return qt_x11_paintengine();
-}
-
-qreal QX11PlatformPixmap::devicePixelRatio() const
-{
- return dpr;
-}
-
-void QX11PlatformPixmap::setDevicePixelRatio(qreal scaleFactor)
-{
- dpr = scaleFactor;
-}
-
-Pixmap QX11PlatformPixmap::x11ConvertToDefaultDepth()
-{
-#if QT_CONFIG(xrender)
- if (d == xinfo.appDepth() || !X11->use_xrender)
- return hd;
- if (!hd2) {
- hd2 = XCreatePixmap(xinfo.display(), hd, w, h, xinfo.appDepth());
- XRenderPictFormat *format = XRenderFindVisualFormat(xinfo.display(),
- (Visual*) xinfo.visual());
- Picture pic = XRenderCreatePicture(xinfo.display(), hd2, format, 0, 0);
- XRenderComposite(xinfo.display(), PictOpSrc, picture,
- XNone, pic, 0, 0, 0, 0, 0, 0, w, h);
- XRenderFreePicture(xinfo.display(), pic);
- }
- return hd2;
-#else
- return hd;
-#endif
-}
-
-XID QX11PlatformPixmap::createBitmapFromImage(const QImage &image)
-{
- QImage img = image.convertToFormat(QImage::Format_MonoLSB);
- const QRgb c0 = QColor(Qt::black).rgb();
- const QRgb c1 = QColor(Qt::white).rgb();
- if (img.color(0) == c0 && img.color(1) == c1) {
- img.invertPixels();
- img.setColor(0, c1);
- img.setColor(1, c0);
- }
-
- char *bits;
- uchar *tmp_bits;
- int w = img.width();
- int h = img.height();
- int bpl = (w + 7) / 8;
- qsizetype ibpl = img.bytesPerLine();
- if (bpl != ibpl) {
- tmp_bits = new uchar[bpl*h];
- bits = (char *)tmp_bits;
- uchar *p, *b;
- int y;
- b = tmp_bits;
- p = img.scanLine(0);
- for (y = 0; y < h; y++) {
- memcpy(b, p, bpl);
- b += bpl;
- p += ibpl;
- }
- } else {
- bits = (char *)img.bits();
- tmp_bits = 0;
- }
- XID hd = XCreateBitmapFromData(QXcbX11Info::display(),
- QXcbX11Info::appRootWindow(),
- bits, w, h);
- if (tmp_bits) // Avoid purify complaint
- delete [] tmp_bits;
- return hd;
-}
-
-bool QX11PlatformPixmap::isBackingStore() const
-{
- return (flags & IsBackingStore);
-}
-
-void QX11PlatformPixmap::setIsBackingStore(bool on)
-{
- if (on)
- flags |= IsBackingStore;
- else {
- flags &= ~IsBackingStore;
- }
-}
-
-#if QT_CONFIG(xrender)
-void QX11PlatformPixmap::convertToARGB32(bool preserveContents)
-{
- if (!X11->use_xrender)
- return;
-
- // Q_ASSERT(count == 1);
- if ((flags & Readonly)/* && share_mode == QPixmap::ExplicitlyShared*/)
- return;
-
- Pixmap pm = XCreatePixmap(xinfo.display(), RootWindow(xinfo.display(), xinfo.screen()),
- w, h, 32);
- Picture p = XRenderCreatePicture(xinfo.display(), pm,
- XRenderFindStandardFormat(xinfo.display(), PictStandardARGB32), 0, 0);
- if (picture) {
- if (preserveContents)
- XRenderComposite(xinfo.display(), PictOpSrc, picture, 0, p, 0, 0, 0, 0, 0, 0, w, h);
- if (!(flags & Readonly))
- XRenderFreePicture(xinfo.display(), picture);
- }
- if (hd && !(flags & Readonly))
- XFreePixmap(xinfo.display(), hd);
- if (x11_mask) {
- XFreePixmap(xinfo.display(), x11_mask);
- if (mask_picture)
- XRenderFreePicture(xinfo.display(), mask_picture);
- x11_mask = 0;
- mask_picture = 0;
- }
- hd = pm;
- picture = p;
-
- d = 32;
- xinfo.setDepth(32);
-
- XVisualInfo visinfo;
- if (XMatchVisualInfo(xinfo.display(), xinfo.screen(), 32, TrueColor, &visinfo))
- xinfo.setVisual(visinfo.visual);
-}
-#endif
-
-void QX11PlatformPixmap::release()
-{
- delete pengine;
- pengine = 0;
-
- if (/*!X11*/ QCoreApplication::closingDown()) {
- // At this point, the X server will already have freed our resources,
- // so there is nothing to do.
- return;
- }
-
- if (x11_mask) {
-#if QT_CONFIG(xrender)
- if (mask_picture)
- XRenderFreePicture(xinfo.display(), mask_picture);
- mask_picture = 0;
-#endif
- XFreePixmap(xinfo.display(), x11_mask);
- x11_mask = 0;
- }
-
- if (hd) {
-#if QT_CONFIG(xrender)
- if (picture) {
- XRenderFreePicture(xinfo.display(), picture);
- picture = 0;
- }
-#endif // QT_CONFIG(xrender)
-
- if (hd2) {
- XFreePixmap(xinfo.display(), hd2);
- hd2 = 0;
- }
- if (!(flags & Readonly))
- XFreePixmap(xinfo.display(), hd);
- hd = 0;
- }
-}
-
-QImage QX11PlatformPixmap::toImage(const QXImageWrapper &xiWrapper, const QRect &rect) const
-{
- XImage *xi = xiWrapper.xi;
-
- int d = depth();
- Visual *visual = (Visual *)xinfo.visual();
- bool trucol = (visual->c_class >= TrueColor) && d > 1;
-
- QImage::Format format = QImage::Format_Mono;
- if (d > 1 && d <= 8) {
- d = 8;
- format = QImage::Format_Indexed8;
- }
- // we could run into the situation where d == 8 AND trucol is true, which can
- // cause problems when converting to and from images. in this case, always treat
- // the depth as 32...
- if (d > 8 || trucol) {
- d = 32;
- format = QImage::Format_RGB32;
- }
-
- if (d == 1 && xi->bitmap_bit_order == LSBFirst)
- format = QImage::Format_MonoLSB;
- if (x11_mask && format == QImage::Format_RGB32)
- format = QImage::Format_ARGB32;
-
- QImage image(xi->width, xi->height, format);
- image.setDevicePixelRatio(devicePixelRatio());
- if (image.isNull()) // could not create image
- return image;
-
- QImage alpha;
- if (x11_mask) {
- if (rect.contains(QRect(0, 0, w, h)))
- alpha = mask().toImage();
- else
- alpha = mask().toImage().copy(rect);
- }
- bool ale = alpha.format() == QImage::Format_MonoLSB;
-
- if (trucol) { // truecolor
- const uint red_mask = (uint)visual->red_mask;
- const uint green_mask = (uint)visual->green_mask;
- const uint blue_mask = (uint)visual->blue_mask;
- const int red_shift = highest_bit(red_mask) - 7;
- const int green_shift = highest_bit(green_mask) - 7;
- const int blue_shift = highest_bit(blue_mask) - 7;
-
- const uint red_bits = n_bits(red_mask);
- const uint green_bits = n_bits(green_mask);
- const uint blue_bits = n_bits(blue_mask);
-
- static uint red_table_bits = 0;
- static uint green_table_bits = 0;
- static uint blue_table_bits = 0;
-
- if (red_bits < 8 && red_table_bits != red_bits) {
- build_scale_table(&red_scale_table, red_bits);
- red_table_bits = red_bits;
- }
- if (blue_bits < 8 && blue_table_bits != blue_bits) {
- build_scale_table(&blue_scale_table, blue_bits);
- blue_table_bits = blue_bits;
- }
- if (green_bits < 8 && green_table_bits != green_bits) {
- build_scale_table(&green_scale_table, green_bits);
- green_table_bits = green_bits;
- }
-
- int r, g, b;
-
- QRgb *dst;
- uchar *src;
- uint pixel;
- int bppc = xi->bits_per_pixel;
-
- if (bppc > 8 && xi->byte_order == LSBFirst)
- bppc++;
-
- for (int y = 0; y < xi->height; ++y) {
- uchar* asrc = x11_mask ? alpha.scanLine(y) : 0;
- dst = (QRgb *)image.scanLine(y);
- src = (uchar *)xi->data + xi->bytes_per_line*y;
- for (int x = 0; x < xi->width; x++) {
- switch (bppc) {
- case 8:
- pixel = *src++;
- break;
- case 16: // 16 bit MSB
- pixel = src[1] | (uint)src[0] << 8;
- src += 2;
- break;
- case 17: // 16 bit LSB
- pixel = src[0] | (uint)src[1] << 8;
- src += 2;
- break;
- case 24: // 24 bit MSB
- pixel = src[2] | (uint)src[1] << 8 | (uint)src[0] << 16;
- src += 3;
- break;
- case 25: // 24 bit LSB
- pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16;
- src += 3;
- break;
- case 32: // 32 bit MSB
- pixel = src[3] | (uint)src[2] << 8 | (uint)src[1] << 16 | (uint)src[0] << 24;
- src += 4;
- break;
- case 33: // 32 bit LSB
- pixel = src[0] | (uint)src[1] << 8 | (uint)src[2] << 16 | (uint)src[3] << 24;
- src += 4;
- break;
- default: // should not really happen
- x = xi->width; // leave loop
- y = xi->height;
- pixel = 0; // eliminate compiler warning
- qWarning("QPixmap::convertToImage: Invalid depth %d", bppc);
- }
- if (red_shift > 0)
- r = (pixel & red_mask) >> red_shift;
- else
- r = (pixel & red_mask) << -red_shift;
- if (green_shift > 0)
- g = (pixel & green_mask) >> green_shift;
- else
- g = (pixel & green_mask) << -green_shift;
- if (blue_shift > 0)
- b = (pixel & blue_mask) >> blue_shift;
- else
- b = (pixel & blue_mask) << -blue_shift;
-
- if (red_bits < 8)
- r = red_scale_table[r];
- if (green_bits < 8)
- g = green_scale_table[g];
- if (blue_bits < 8)
- b = blue_scale_table[b];
-
- if (x11_mask) {
- if (ale) {
- *dst++ = (asrc[x >> 3] & (1 << (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
- } else {
- *dst++ = (asrc[x >> 3] & (0x80 >> (x & 7))) ? qRgba(r, g, b, 0xff) : 0;
- }
- } else {
- *dst++ = qRgb(r, g, b);
- }
- }
- }
- } else if (xi->bits_per_pixel == d) { // compatible depth
- char *xidata = xi->data; // copy each scanline
- qsizetype bpl = qMin(image.bytesPerLine(),xi->bytes_per_line);
- for (int y=0; y<xi->height; y++) {
- memcpy(image.scanLine(y), xidata, bpl);
- xidata += xi->bytes_per_line;
- }
- } else {
- /* Typically 2 or 4 bits display depth */
- qWarning("QPixmap::convertToImage: Display not supported (bpp=%d)",
- xi->bits_per_pixel);
- return QImage();
- }
-
- if (d == 1) { // bitmap
- image.setColorCount(2);
- image.setColor(0, qRgb(255,255,255));
- image.setColor(1, qRgb(0,0,0));
- } else if (!trucol) { // pixmap with colormap
- uchar *p;
- uchar *end;
- uchar use[256]; // pixel-in-use table
- uchar pix[256]; // pixel translation table
- int ncols;
- memset(use, 0, 256);
- memset(pix, 0, 256);
- qsizetype bpl = image.bytesPerLine();
-
- if (x11_mask) { // which pixels are used?
- for (int i = 0; i < xi->height; i++) {
- uchar* asrc = alpha.scanLine(i);
- p = image.scanLine(i);
- if (ale) {
- for (int x = 0; x < xi->width; x++) {
- if (asrc[x >> 3] & (1 << (x & 7)))
- use[*p] = 1;
- ++p;
- }
- } else {
- for (int x = 0; x < xi->width; x++) {
- if (asrc[x >> 3] & (0x80 >> (x & 7)))
- use[*p] = 1;
- ++p;
- }
- }
- }
- } else {
- for (int i = 0; i < xi->height; i++) {
- p = image.scanLine(i);
- end = p + bpl;
- while (p < end)
- use[*p++] = 1;
- }
- }
- ncols = 0;
- for (int i = 0; i < 256; i++) { // build translation table
- if (use[i])
- pix[i] = ncols++;
- }
- for (int i = 0; i < xi->height; i++) { // translate pixels
- p = image.scanLine(i);
- end = p + bpl;
- while (p < end) {
- *p = pix[*p];
- p++;
- }
- }
- if (x11_mask) {
- int trans;
- if (ncols < 256) {
- trans = ncols++;
- image.setColorCount(ncols); // create color table
- image.setColor(trans, 0x00000000);
- } else {
- image.setColorCount(ncols); // create color table
- // oh dear... no spare "transparent" pixel.
- // use first pixel in image (as good as any).
- trans = image.scanLine(0)[0];
- }
- for (int i = 0; i < xi->height; i++) {
- uchar* asrc = alpha.scanLine(i);
- p = image.scanLine(i);
- if (ale) {
- for (int x = 0; x < xi->width; x++) {
- if (!(asrc[x >> 3] & (1 << (x & 7))))
- *p = trans;
- ++p;
- }
- } else {
- for (int x = 0; x < xi->width; x++) {
- if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
- *p = trans;
- ++p;
- }
- }
- }
- } else {
- image.setColorCount(ncols); // create color table
- }
- QList<QColor> colors = QXcbColormap::instance(xinfo.screen()).colormap();
- int j = 0;
- for (int i=0; i<colors.size(); i++) { // translate pixels
- if (use[i])
- image.setColor(j++, 0xff000000 | colors.at(i).rgb());
- }
- }
-
- return image;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h
deleted file mode 100644
index 0755a34b4a8..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qpixmap_x11_p.h
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-#include <QBitmap>
-#include <QPixmap>
-
-#include <qpa/qplatformpixmap.h>
-#include "qxcbnativepainting.h"
-
-typedef unsigned long XID;
-typedef XID Drawable;
-typedef XID Picture;
-typedef XID Pixmap;
-
-QT_BEGIN_NAMESPACE
-
-class QX11PaintEngine;
-struct QXImageWrapper;
-
-class QX11PlatformPixmap : public QPlatformPixmap
-{
-public:
- QX11PlatformPixmap(PixelType pixelType);
- ~QX11PlatformPixmap();
-
- QPlatformPixmap *createCompatiblePlatformPixmap() const override;
- void resize(int width, int height) override;
- void fromImage(const QImage &img, Qt::ImageConversionFlags flags) override;
- void copy(const QPlatformPixmap *data, const QRect &rect) override;
- bool scroll(int dx, int dy, const QRect &rect) override;
- int metric(QPaintDevice::PaintDeviceMetric metric) const override;
- void fill(const QColor &fillColor) override;
- QBitmap mask() const override;
- void setMask(const QBitmap &mask) override;
- bool hasAlphaChannel() const override;
- QPixmap transformed(const QTransform &matrix, Qt::TransformationMode mode) const override;
- QImage toImage() const override;
- QImage toImage(const QRect &rect) const override;
- QPaintEngine *paintEngine() const override;
- qreal devicePixelRatio() const override;
- void setDevicePixelRatio(qreal scaleFactor) override;
-
- inline Drawable handle() const { return hd; }
- inline Picture x11PictureHandle() const { return picture; }
- inline const QXcbX11Info *x11_info() const { return &xinfo; }
-
- Pixmap x11ConvertToDefaultDepth();
- static XID createBitmapFromImage(const QImage &image);
-
-#if QT_CONFIG(xrender)
- void convertToARGB32(bool preserveContents = true);
-#endif
-
- bool isBackingStore() const;
- void setIsBackingStore(bool on);
-private:
- friend class QX11PaintEngine;
- friend const QXcbX11Info &qt_x11Info(const QPixmap &pixmap);
- friend void qt_x11SetScreen(QPixmap &pixmap, int screen);
-
- void release();
- QImage toImage(const QXImageWrapper &xi, const QRect &rect) const;
- QBitmap mask_to_bitmap(int screen) const;
- static Pixmap bitmap_to_mask(const QBitmap &, int screen);
- void bitmapFromImage(const QImage &image);
- bool canTakeQImageFromXImage(const QXImageWrapper &xi) const;
- QImage takeQImageFromXImage(const QXImageWrapper &xi) const;
-
- Pixmap hd = 0;
-
- enum Flag {
- NoFlags = 0x0,
- Uninitialized = 0x1,
- Readonly = 0x2,
- InvertedWhenBoundToTexture = 0x4,
- GlSurfaceCreatedWithAlpha = 0x8,
- IsBackingStore = 0x10
- };
- uint flags;
-
- QXcbX11Info xinfo;
- Pixmap x11_mask;
- Picture picture;
- Picture mask_picture;
- Pixmap hd2; // sorted in the default display depth
- //QPixmap::ShareMode share_mode;
- qreal dpr;
-
- QX11PaintEngine *pengine;
-};
-
-inline QX11PlatformPixmap *qt_x11Pixmap(const QPixmap &pixmap)
-{
- return (pixmap.handle() && pixmap.handle()->classId() == QPlatformPixmap::X11Class)
- ? static_cast<QX11PlatformPixmap *>(pixmap.handle())
- : nullptr;
-}
-
-inline Picture qt_x11PictureHandle(const QPixmap &pixmap)
-{
- if (QX11PlatformPixmap *pm = qt_x11Pixmap(pixmap))
- return pm->x11PictureHandle();
-
- return 0;
-}
-
-inline Pixmap qt_x11PixmapHandle(const QPixmap &pixmap)
-{
- if (QX11PlatformPixmap *pm = qt_x11Pixmap(pixmap))
- return pm->handle();
-
- return 0;
-}
-
-inline const QXcbX11Info &qt_x11Info(const QPixmap &pixmap)
-{
- if (QX11PlatformPixmap *pm = qt_x11Pixmap(pixmap)) {
- return pm->xinfo;
- } else {
- static QXcbX11Info nullX11Info;
- return nullX11Info;
- }
-}
-
-int qt_x11SetDefaultScreen(int screen);
-void qt_x11SetScreen(QPixmap &pixmap, int screen);
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qpolygonclipper_p.h b/src/plugins/platforms/xcb/nativepainting/qpolygonclipper_p.h
deleted file mode 100644
index e1e31722d76..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qpolygonclipper_p.h
+++ /dev/null
@@ -1,278 +0,0 @@
-// Copyright (C) 2016 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of other Qt classes. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qrect.h>
-#include <QtGui/private/qdatabuffer_p.h>
-
-QT_BEGIN_NAMESPACE
-
-/* based on sutherland-hodgman line-by-line clipping, as described in
- Computer Graphics and Principles */
-template <typename InType, typename OutType, typename CastType> class QPolygonClipper
-{
-public:
- QPolygonClipper() :
- buffer1(0), buffer2(0)
- {
- x1 = y1 = x2 = y2 = 0;
- }
-
- ~QPolygonClipper()
- {
- }
-
- void setBoundingRect(const QRect bounds)
- {
- x1 = bounds.x();
- x2 = bounds.x() + bounds.width();
- y1 = bounds.y();
- y2 = bounds.y() + bounds.height();
- }
-
- QRect boundingRect()
- {
- return QRect(QPoint(x1, y1), QPoint(x2, y2));
- }
-
- inline OutType intersectLeft(const OutType &p1, const OutType &p2)
- {
- OutType t;
- qreal dy = (p1.y - p2.y) / qreal(p1.x - p2.x);
- t.x = x1;
- t.y = static_cast<CastType>(p2.y + (x1 - p2.x) * dy);
- return t;
- }
-
-
- inline OutType intersectRight(const OutType &p1, const OutType &p2)
- {
- OutType t;
- qreal dy = (p1.y - p2.y) / qreal(p1.x - p2.x);
- t.x = x2;
- t.y = static_cast<CastType>(p2.y + (x2 - p2.x) * dy);
- return t;
- }
-
-
- inline OutType intersectTop(const OutType &p1, const OutType &p2)
- {
- OutType t;
- qreal dx = (p1.x - p2.x) / qreal(p1.y - p2.y);
- t.x = static_cast<CastType>(p2.x + (y1 - p2.y) * dx);
- t.y = y1;
- return t;
- }
-
-
- inline OutType intersectBottom(const OutType &p1, const OutType &p2)
- {
- OutType t;
- qreal dx = (p1.x - p2.x) / qreal(p1.y - p2.y);
- t.x = static_cast<CastType>(p2.x + (y2 - p2.y) * dx);
- t.y = y2;
- return t;
- }
-
-
- void clipPolygon(const InType *inPoints, int inCount, OutType **outPoints, int *outCount,
- bool closePolygon = true)
- {
- Q_ASSERT(outPoints);
- Q_ASSERT(outCount);
-
- if (inCount < 2) {
- *outCount = 0;
- return;
- }
-
- buffer1.reset();
- buffer2.reset();
-
- QDataBuffer<OutType> *source = &buffer1;
- QDataBuffer<OutType> *clipped = &buffer2;
-
- // Gather some info since we are iterating through the points anyway..
- bool doLeft = false, doRight = false, doTop = false, doBottom = false;
- OutType ot;
- for (int i=0; i<inCount; ++i) {
- ot = inPoints[i];
- clipped->add(ot);
-
- if (ot.x < x1)
- doLeft = true;
- else if (ot.x > x2)
- doRight = true;
- if (ot.y < y1)
- doTop = true;
- else if (ot.y > y2)
- doBottom = true;
- }
-
- if (doLeft && clipped->size() > 1) {
- QDataBuffer<OutType> *tmp = source;
- source = clipped;
- clipped = tmp;
- clipped->reset();
- int lastPos, start;
- if (closePolygon) {
- lastPos = source->size() - 1;
- start = 0;
- } else {
- lastPos = 0;
- start = 1;
- if (source->at(0).x >= x1)
- clipped->add(source->at(0));
- }
- for (int i=start; i<inCount; ++i) {
- const OutType &cpt = source->at(i);
- const OutType &ppt = source->at(lastPos);
-
- if (cpt.x >= x1) {
- if (ppt.x >= x1) {
- clipped->add(cpt);
- } else {
- clipped->add(intersectLeft(cpt, ppt));
- clipped->add(cpt);
- }
- } else if (ppt.x >= x1) {
- clipped->add(intersectLeft(cpt, ppt));
- }
- lastPos = i;
- }
- }
-
- if (doRight && clipped->size() > 1) {
- QDataBuffer<OutType> *tmp = source;
- source = clipped;
- clipped = tmp;
- clipped->reset();
- int lastPos, start;
- if (closePolygon) {
- lastPos = source->size() - 1;
- start = 0;
- } else {
- lastPos = 0;
- start = 1;
- if (source->at(0).x <= x2)
- clipped->add(source->at(0));
- }
- for (int i=start; i<source->size(); ++i) {
- const OutType &cpt = source->at(i);
- const OutType &ppt = source->at(lastPos);
-
- if (cpt.x <= x2) {
- if (ppt.x <= x2) {
- clipped->add(cpt);
- } else {
- clipped->add(intersectRight(cpt, ppt));
- clipped->add(cpt);
- }
- } else if (ppt.x <= x2) {
- clipped->add(intersectRight(cpt, ppt));
- }
-
- lastPos = i;
- }
-
- }
-
- if (doTop && clipped->size() > 1) {
- QDataBuffer<OutType> *tmp = source;
- source = clipped;
- clipped = tmp;
- clipped->reset();
- int lastPos, start;
- if (closePolygon) {
- lastPos = source->size() - 1;
- start = 0;
- } else {
- lastPos = 0;
- start = 1;
- if (source->at(0).y >= y1)
- clipped->add(source->at(0));
- }
- for (int i=start; i<source->size(); ++i) {
- const OutType &cpt = source->at(i);
- const OutType &ppt = source->at(lastPos);
-
- if (cpt.y >= y1) {
- if (ppt.y >= y1) {
- clipped->add(cpt);
- } else {
- clipped->add(intersectTop(cpt, ppt));
- clipped->add(cpt);
- }
- } else if (ppt.y >= y1) {
- clipped->add(intersectTop(cpt, ppt));
- }
-
- lastPos = i;
- }
- }
-
- if (doBottom && clipped->size() > 1) {
- QDataBuffer<OutType> *tmp = source;
- source = clipped;
- clipped = tmp;
- clipped->reset();
- int lastPos, start;
- if (closePolygon) {
- lastPos = source->size() - 1;
- start = 0;
- } else {
- lastPos = 0;
- start = 1;
- if (source->at(0).y <= y2)
- clipped->add(source->at(0));
- }
- for (int i=start; i<source->size(); ++i) {
- const OutType &cpt = source->at(i);
- const OutType &ppt = source->at(lastPos);
-
- if (cpt.y <= y2) {
- if (ppt.y <= y2) {
- clipped->add(cpt);
- } else {
- clipped->add(intersectBottom(cpt, ppt));
- clipped->add(cpt);
- }
- } else if (ppt.y <= y2) {
- clipped->add(intersectBottom(cpt, ppt));
- }
- lastPos = i;
- }
- }
-
- if (closePolygon && clipped->size() > 0) {
- // close clipped polygon
- if (clipped->at(0).x != clipped->at(clipped->size()-1).x ||
- clipped->at(0).y != clipped->at(clipped->size()-1).y) {
- OutType ot = clipped->at(0);
- clipped->add(ot);
- }
- }
- *outCount = clipped->size();
- *outPoints = clipped->data();
- }
-
-private:
- int x1, x2, y1, y2;
- QDataBuffer<OutType> buffer1;
- QDataBuffer<OutType> buffer2;
-};
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h b/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h
deleted file mode 100644
index 2986b8f1453..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qt_x11_p.h
+++ /dev/null
@@ -1,163 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-#define register /* C++17 deprecated register */
-#include <X11/Xlib.h>
-#include <X11/Xatom.h>
-#undef register
-
-#if QT_CONFIG(xrender)
-# include "qtessellator_p.h"
-# include <X11/extensions/Xrender.h>
-#endif
-
-#if QT_CONFIG(fontconfig)
-#include <fontconfig/fontconfig.h>
-#endif
-
-#if defined(FT_LCD_FILTER_H)
-#include FT_LCD_FILTER_H
-#endif
-
-#if defined(FC_LCD_FILTER)
-
-#ifndef FC_LCD_FILTER_NONE
-#define FC_LCD_FILTER_NONE FC_LCD_NONE
-#endif
-
-#ifndef FC_LCD_FILTER_DEFAULT
-#define FC_LCD_FILTER_DEFAULT FC_LCD_DEFAULT
-#endif
-
-#ifndef FC_LCD_FILTER_LIGHT
-#define FC_LCD_FILTER_LIGHT FC_LCD_LIGHT
-#endif
-
-#ifndef FC_LCD_FILTER_LEGACY
-#define FC_LCD_FILTER_LEGACY FC_LCD_LEGACY
-#endif
-
-#endif
-
-QT_BEGIN_NAMESPACE
-
-// rename a couple of X defines to get rid of name clashes
-// resolve the conflict between X11's FocusIn and QEvent::FocusIn
-enum {
- XFocusOut = FocusOut,
- XFocusIn = FocusIn,
- XKeyPress = KeyPress,
- XKeyRelease = KeyRelease,
- XNone = None,
- XRevertToParent = RevertToParent,
- XGrayScale = GrayScale,
- XCursorShape = CursorShape,
-};
-#undef FocusOut
-#undef FocusIn
-#undef KeyPress
-#undef KeyRelease
-#undef None
-#undef RevertToParent
-#undef GrayScale
-#undef CursorShape
-
-#ifdef FontChange
-#undef FontChange
-#endif
-
-Q_DECLARE_TYPEINFO(XPoint, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(XRectangle, Q_PRIMITIVE_TYPE);
-Q_DECLARE_TYPEINFO(XChar2b, Q_PRIMITIVE_TYPE);
-#if QT_CONFIG(xrender)
-Q_DECLARE_TYPEINFO(XGlyphElt32, Q_PRIMITIVE_TYPE);
-#endif
-
-struct QX11InfoData;
-
-enum DesktopEnvironment {
- DE_UNKNOWN,
- DE_KDE,
- DE_GNOME,
- DE_CDE,
- DE_MEEGO_COMPOSITOR,
- DE_4DWM
-};
-
-struct QXcbX11Data {
- Display *display = nullptr;
-
- // true if Qt is compiled w/ RENDER support and RENDER is supported on the connected Display
- bool use_xrender = false;
- int xrender_major = 0;
- int xrender_version = 0;
-
- QX11InfoData *screens = nullptr;
- Visual **argbVisuals = nullptr;
- Colormap *argbColormaps = nullptr;
- int screenCount = 0;
- int defaultScreen = 0;
-
- // options
- int visual_class = 0;
- int visual_id = 0;
- int color_count = 0;
- bool custom_cmap = false;
-
- // outside visual/colormap
- Visual *visual = nullptr;
- Colormap colormap = 0;
-
-#if QT_CONFIG(xrender)
- enum { solid_fill_count = 16 };
- struct SolidFills {
- XRenderColor color;
- int screen;
- Picture picture;
- } solid_fills[solid_fill_count];
- enum { pattern_fill_count = 16 };
- struct PatternFills {
- XRenderColor color;
- XRenderColor bg_color;
- int screen;
- int style;
- bool opaque;
- Picture picture;
- } pattern_fills[pattern_fill_count];
- Picture getSolidFill(int screen, const QColor &c);
- XRenderColor preMultiply(const QColor &c);
-#endif
-
- bool fc_antialias = true;
- int fc_hint_style = 0;
-
- DesktopEnvironment desktopEnvironment = DE_GNOME;
-};
-
-extern QXcbX11Data *qt_x11Data;
-#define X11 qt_x11Data
-
-struct QX11InfoData {
- int screen;
- int dpiX;
- int dpiY;
- int depth;
- int cells;
- Colormap colormap;
- Visual *visual;
- bool defaultColormap;
- bool defaultVisual;
- int subpixel = 0;
-};
-
-template <class T>
-constexpr inline int lowest_bit(T v) noexcept
-{
- int result = qCountTrailingZeroBits(v);
- return ((result >> 3) == sizeof(T)) ? -1 : result;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
deleted file mode 100644
index dd83f8852b7..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+++ /dev/null
@@ -1,1466 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#include "qtessellator_p.h"
-
-#include <QRect>
-#include <QList>
-#include <QMap>
-#include <QDebug>
-
-#include <qmath.h>
-#include <limits.h>
-#include <algorithm>
-
-QT_BEGIN_NAMESPACE
-
-//#define DEBUG
-#ifdef DEBUG
-#define QDEBUG qDebug
-#else
-#define QDEBUG if (1){} else qDebug
-#endif
-
-static const bool emit_clever = true;
-static const bool mark_clever = false;
-
-enum VertexFlags {
- LineBeforeStarts = 0x1,
- LineBeforeEnds = 0x2,
- LineBeforeHorizontal = 0x4,
- LineAfterStarts = 0x8,
- LineAfterEnds = 0x10,
- LineAfterHorizontal = 0x20
-};
-
-
-
-class QTessellatorPrivate {
-public:
- struct Vertices;
-
- QTessellatorPrivate() {}
-
- QRectF collectAndSortVertices(const QPointF *points, int *maxActiveEdges);
- void cancelCoincidingEdges();
-
- void emitEdges(QTessellator *tessellator);
- void processIntersections();
- void removeEdges();
- void addEdges();
- void addIntersections();
-
- struct Vertex : public QTessellator::Vertex
- {
- int flags;
- };
-
- struct Intersection
- {
- Q27Dot5 y;
- int edge;
- bool operator <(const Intersection &other) const {
- if (y != other.y)
- return y < other.y;
- return edge < other.edge;
- }
- };
- struct IntersectionLink
- {
- int next;
- int prev;
- };
- typedef QMap<Intersection, IntersectionLink> Intersections;
-
- struct Edge {
- Edge(const Vertices &v, int _edge);
- int edge;
- const Vertex *v0;
- const Vertex *v1;
- Q27Dot5 y_left;
- Q27Dot5 y_right;
- signed int winding : 8;
- bool mark;
- bool free;
- bool intersect_left;
- bool intersect_right;
- bool isLeftOf(const Edge &other, Q27Dot5 y) const;
- Q27Dot5 positionAt(Q27Dot5 y) const;
- bool intersect(const Edge &other, Q27Dot5 *y, bool *det_positive) const;
-
- };
-
- class EdgeSorter
- {
- public:
- EdgeSorter(int _y) : y(_y) {}
- bool operator() (const Edge *e1, const Edge *e2);
- int y;
- };
-
- class Scanline {
- public:
- Scanline();
- ~Scanline();
-
- void init(int maxActiveEdges);
- void done();
-
- int findEdgePosition(Q27Dot5 x, Q27Dot5 y) const;
- int findEdgePosition(const Edge &e) const;
- int findEdge(int edge) const;
- void clearMarks();
-
- void swap(int p1, int p2) {
- Edge *tmp = edges[p1];
- edges[p1] = edges[p2];
- edges[p2] = tmp;
- }
- void insert(int pos, const Edge &e);
- void removeAt(int pos);
- void markEdges(int pos1, int pos2);
-
- void prepareLine();
- void lineDone();
-
- Edge **old;
- int old_size;
-
- Edge **edges;
- int size;
-
- private:
- Edge *edge_table;
- int first_unused;
- int max_edges;
- enum { default_alloc = 32 };
- };
-
- struct Vertices {
- enum { default_alloc = 128 };
- Vertices();
- ~Vertices();
- void init(int maxVertices);
- void done();
- Vertex *storage;
- Vertex **sorted;
-
- Vertex *operator[] (int i) { return storage + i; }
- const Vertex *operator[] (int i) const { return storage + i; }
- int position(const Vertex *v) const {
- return v - storage;
- }
- Vertex *next(Vertex *v) {
- ++v;
- if (v == storage + nPoints)
- v = storage;
- return v;
- }
- const Vertex *next(const Vertex *v) const {
- ++v;
- if (v == storage + nPoints)
- v = storage;
- return v;
- }
- int nextPos(const Vertex *v) const {
- ++v;
- if (v == storage + nPoints)
- return 0;
- return v - storage;
- }
- Vertex *prev(Vertex *v) {
- if (v == storage)
- v = storage + nPoints;
- --v;
- return v;
- }
- const Vertex *prev(const Vertex *v) const {
- if (v == storage)
- v = storage + nPoints;
- --v;
- return v;
- }
- int prevPos(const Vertex *v) const {
- if (v == storage)
- v = storage + nPoints;
- --v;
- return v - storage;
- }
- int nPoints;
- int allocated;
- };
- Vertices vertices;
- Intersections intersections;
- Scanline scanline;
- bool winding;
- Q27Dot5 y;
- int currentVertex;
-
-private:
- void addIntersection(const Edge *e1, const Edge *e2);
- bool edgeInChain(Intersection i, int edge);
-};
-
-
-QTessellatorPrivate::Edge::Edge(const QTessellatorPrivate::Vertices &vertices, int edge)
-{
- this->edge = edge;
- intersect_left = intersect_right = true;
- mark = false;
- free = false;
-
- v0 = vertices[edge];
- v1 = vertices.next(v0);
-
- Q_ASSERT(v0->y != v1->y);
-
- if (v0->y > v1->y) {
- qSwap(v0, v1);
- winding = -1;
- } else {
- winding = 1;
- }
- y_left = y_right = v0->y;
-}
-
-// This is basically the algorithm from graphics gems. The algorithm
-// is cubic in the coordinates at one place. Since we use 64bit
-// integers, this implies, that the allowed range for our coordinates
-// is limited to 21 bits. With 5 bits behind the decimal, this
-// implies that differences in coordaintes can range from 2*SHORT_MIN
-// to 2*SHORT_MAX, giving us efficiently a coordinate system from
-// SHORT_MIN to SHORT_MAX.
-//
-
-// WARNING: It's absolutely critical that the intersect() and isLeftOf() methods use
-// exactly the same algorithm to calculate yi. It's also important to be sure the algorithms
-// are transitive (ie. the conditions below are true for all input data):
-//
-// a.intersect(b) == b.intersect(a)
-// a.isLeftOf(b) != b.isLeftOf(a)
-//
-// This is tricky to get right, so be very careful when changing anything in here!
-
-static inline bool sameSign(qint64 a, qint64 b) {
- return (((qint64) ((quint64) a ^ (quint64) b)) >= 0 );
-}
-
-bool QTessellatorPrivate::Edge::intersect(const Edge &other, Q27Dot5 *y, bool *det_positive) const
-{
- qint64 a1 = v1->y - v0->y;
- qint64 b1 = v0->x - v1->x;
-
- qint64 a2 = other.v1->y - other.v0->y;
- qint64 b2 = other.v0->x - other.v1->x;
-
- qint64 det = a1 * b2 - a2 * b1;
- if (det == 0)
- return false;
-
- qint64 c1 = qint64(v1->x) * v0->y - qint64(v0->x) * v1->y;
-
- qint64 r3 = a1 * other.v0->x + b1 * other.v0->y + c1;
- qint64 r4 = a1 * other.v1->x + b1 * other.v1->y + c1;
-
- // Check signs of r3 and r4. If both point 3 and point 4 lie on
- // same side of line 1, the line segments do not intersect.
- QDEBUG() << " " << r3 << r4;
- if (r3 != 0 && r4 != 0 && sameSign( r3, r4 ))
- return false;
-
- qint64 c2 = qint64(other.v1->x) * other.v0->y - qint64(other.v0->x) * other.v1->y;
-
- qint64 r1 = a2 * v0->x + b2 * v0->y + c2;
- qint64 r2 = a2 * v1->x + b2 * v1->y + c2;
-
- // Check signs of r1 and r2. If both point 1 and point 2 lie
- // on same side of second line segment, the line segments do not intersect.
- QDEBUG() << " " << r1 << r2;
- if (r1 != 0 && r2 != 0 && sameSign( r1, r2 ))
- return false;
-
- // The det/2 is to get rounding instead of truncating. It
- // is added or subtracted to the numerator, depending upon the
- // sign of the numerator.
- qint64 offset = det < 0 ? -det : det;
- offset >>= 1;
-
- qint64 num = a2 * c1 - a1 * c2;
- *y = ( num < 0 ? num - offset : num + offset ) / det;
-
- *det_positive = (det > 0);
-
- return true;
-}
-
-#undef SAME_SIGNS
-
-bool QTessellatorPrivate::Edge::isLeftOf(const Edge &other, Q27Dot5 y) const
-{
-// QDEBUG() << "isLeftOf" << edge << other.edge << y;
- qint64 a1 = v1->y - v0->y;
- qint64 b1 = v0->x - v1->x;
- qint64 a2 = other.v1->y - other.v0->y;
- qint64 b2 = other.v0->x - other.v1->x;
-
- qint64 c2 = qint64(other.v1->x) * other.v0->y - qint64(other.v0->x) * other.v1->y;
-
- qint64 det = a1 * b2 - a2 * b1;
- if (det == 0) {
- // lines are parallel. Only need to check side of one point
- // fixed ordering for coincident edges
- qint64 r1 = a2 * v0->x + b2 * v0->y + c2;
-// QDEBUG() << "det = 0" << r1;
- if (r1 == 0)
- return edge < other.edge;
- return (r1 < 0);
- }
-
- // not parallel, need to find the y coordinate of the intersection point
- qint64 c1 = qint64(v1->x) * v0->y - qint64(v0->x) * v1->y;
-
- qint64 offset = det < 0 ? -det : det;
- offset >>= 1;
-
- qint64 num = a2 * c1 - a1 * c2;
- qint64 yi = ( num < 0 ? num - offset : num + offset ) / det;
-// QDEBUG() << " num=" << num << "offset=" << offset << "det=" << det;
-
- return ((yi > y) ^ (det < 0));
-}
-
-static inline bool compareVertex(const QTessellatorPrivate::Vertex *p1,
- const QTessellatorPrivate::Vertex *p2)
-{
- if (p1->y == p2->y) {
- if (p1->x == p2->x)
- return p1 < p2;
- return p1->x < p2->x;
- }
- return p1->y < p2->y;
-}
-
-Q27Dot5 QTessellatorPrivate::Edge::positionAt(Q27Dot5 y) const
-{
- if (y == v0->y)
- return v0->x;
- else if (y == v1->y)
- return v1->x;
-
- qint64 d = v1->x - v0->x;
- return (v0->x + d*(y - v0->y)/(v1->y-v0->y));
-}
-
-bool QTessellatorPrivate::EdgeSorter::operator() (const Edge *e1, const Edge *e2)
-{
- return e1->isLeftOf(*e2, y);
-}
-
-
-QTessellatorPrivate::Scanline::Scanline()
-{
- edges = 0;
- edge_table = 0;
- old = 0;
-}
-
-void QTessellatorPrivate::Scanline::init(int maxActiveEdges)
-{
- maxActiveEdges *= 2;
- if (!edges || maxActiveEdges > default_alloc) {
- max_edges = maxActiveEdges;
- int s = qMax(maxActiveEdges + 1, default_alloc + 1);
- edges = q_check_ptr((Edge **)realloc(edges, s*sizeof(Edge *)));
- edge_table = q_check_ptr((Edge *)realloc(edge_table, s*sizeof(Edge)));
- old = q_check_ptr((Edge **)realloc(old, s*sizeof(Edge *)));
- }
- size = 0;
- old_size = 0;
- first_unused = 0;
- for (int i = 0; i < maxActiveEdges; ++i)
- edge_table[i].edge = i+1;
- edge_table[maxActiveEdges].edge = -1;
-}
-
-void QTessellatorPrivate::Scanline::done()
-{
- if (max_edges > default_alloc) {
- free(edges);
- free(old);
- free(edge_table);
- edges = 0;
- old = 0;
- edge_table = 0;
- }
-}
-
-QTessellatorPrivate::Scanline::~Scanline()
-{
- free(edges);
- free(old);
- free(edge_table);
-}
-
-int QTessellatorPrivate::Scanline::findEdgePosition(Q27Dot5 x, Q27Dot5 y) const
-{
- int min = 0;
- int max = size - 1;
- while (min < max) {
- int pos = min + ((max - min + 1) >> 1);
- Q27Dot5 ax = edges[pos]->positionAt(y);
- if (ax > x) {
- max = pos - 1;
- } else {
- min = pos;
- }
- }
- return min;
-}
-
-int QTessellatorPrivate::Scanline::findEdgePosition(const Edge &e) const
-{
-// qDebug() << ">> findEdgePosition";
- int min = 0;
- int max = size;
- while (min < max) {
- int pos = min + ((max - min) >> 1);
-// qDebug() << " " << min << max << pos << edges[pos]->isLeftOf(e, e.y0);
- if (edges[pos]->isLeftOf(e, e.v0->y)) {
- min = pos + 1;
- } else {
- max = pos;
- }
- }
-// qDebug() << "<< findEdgePosition got" << min;
- return min;
-}
-
-int QTessellatorPrivate::Scanline::findEdge(int edge) const
-{
- for (int i = 0; i < size; ++i) {
- int item_edge = edges[i]->edge;
- if (item_edge == edge)
- return i;
- }
- //Q_ASSERT(false);
- return -1;
-}
-
-void QTessellatorPrivate::Scanline::clearMarks()
-{
- for (int i = 0; i < size; ++i) {
- edges[i]->mark = false;
- edges[i]->intersect_left = false;
- edges[i]->intersect_right = false;
- }
-}
-
-void QTessellatorPrivate::Scanline::prepareLine()
-{
- Edge **end = edges + size;
- Edge **e = edges;
- Edge **o = old;
- while (e < end) {
- *o = *e;
- ++o;
- ++e;
- }
- old_size = size;
-}
-
-void QTessellatorPrivate::Scanline::lineDone()
-{
- Edge **end = old + old_size;
- Edge **e = old;
- while (e < end) {
- if ((*e)->free) {
- (*e)->edge = first_unused;
- first_unused = (*e - edge_table);
- }
- ++e;
- }
-}
-
-void QTessellatorPrivate::Scanline::insert(int pos, const Edge &e)
-{
- Edge *edge = edge_table + first_unused;
- first_unused = edge->edge;
- Q_ASSERT(first_unused != -1);
- *edge = e;
- memmove(edges + pos + 1, edges + pos, (size - pos)*sizeof(Edge *));
- edges[pos] = edge;
- ++size;
-}
-
-void QTessellatorPrivate::Scanline::removeAt(int pos)
-{
- Edge *e = edges[pos];
- e->free = true;
- --size;
- memmove(edges + pos, edges + pos + 1, (size - pos)*sizeof(Edge *));
-}
-
-void QTessellatorPrivate::Scanline::markEdges(int pos1, int pos2)
-{
- if (pos2 < pos1)
- return;
-
- for (int i = pos1; i <= pos2; ++i)
- edges[i]->mark = true;
-}
-
-
-QTessellatorPrivate::Vertices::Vertices()
-{
- storage = 0;
- sorted = 0;
- allocated = 0;
- nPoints = 0;
-}
-
-QTessellatorPrivate::Vertices::~Vertices()
-{
- if (storage) {
- free(storage);
- free(sorted);
- }
-}
-
-void QTessellatorPrivate::Vertices::init(int maxVertices)
-{
- if (!storage || maxVertices > allocated) {
- int size = qMax((int)default_alloc, maxVertices);
- storage = q_check_ptr((Vertex *)realloc(storage, size*sizeof(Vertex)));
- sorted = q_check_ptr((Vertex **)realloc(sorted, size*sizeof(Vertex *)));
- allocated = maxVertices;
- }
-}
-
-void QTessellatorPrivate::Vertices::done()
-{
- if (allocated > default_alloc) {
- free(storage);
- free(sorted);
- storage = 0;
- sorted = 0;
- allocated = 0;
- }
-}
-
-
-
-static inline void fillTrapezoid(Q27Dot5 y1, Q27Dot5 y2, int left, int right,
- const QTessellatorPrivate::Vertices &vertices,
- QTessellator::Trapezoid *trap)
-{
- trap->top = y1;
- trap->bottom = y2;
- const QTessellatorPrivate::Vertex *v = vertices[left];
- trap->topLeft = v;
- trap->bottomLeft = vertices.next(v);
- if (trap->topLeft->y > trap->bottomLeft->y)
- qSwap(trap->topLeft,trap->bottomLeft);
- v = vertices[right];
- trap->topRight = v;
- trap->bottomRight = vertices.next(v);
- if (trap->topRight->y > trap->bottomRight->y)
- qSwap(trap->topRight, trap->bottomRight);
-}
-
-QRectF QTessellatorPrivate::collectAndSortVertices(const QPointF *points, int *maxActiveEdges)
-{
- *maxActiveEdges = 0;
- Vertex *v = vertices.storage;
- Vertex **vv = vertices.sorted;
-
- qreal xmin(points[0].x());
- qreal xmax(points[0].x());
- qreal ymin(points[0].y());
- qreal ymax(points[0].y());
-
- // collect vertex data
- Q27Dot5 y_prev = FloatToQ27Dot5(points[vertices.nPoints-1].y());
- Q27Dot5 x_next = FloatToQ27Dot5(points[0].x());
- Q27Dot5 y_next = FloatToQ27Dot5(points[0].y());
- int j = 0;
- int i = 0;
- while (i < vertices.nPoints) {
- Q27Dot5 y_curr = y_next;
-
- *vv = v;
-
- v->x = x_next;
- v->y = y_next;
- v->flags = 0;
-
- next_point:
-
- xmin = qMin(xmin, points[i+1].x());
- xmax = qMax(xmax, points[i+1].x());
- ymin = qMin(ymin, points[i+1].y());
- ymax = qMax(ymax, points[i+1].y());
-
- y_next = FloatToQ27Dot5(points[i+1].y());
- x_next = FloatToQ27Dot5(points[i+1].x());
-
- // skip vertices on top of each other
- if (v->x == x_next && v->y == y_next) {
- ++i;
- if (i < vertices.nPoints)
- goto next_point;
- Vertex *v0 = vertices.storage;
- v0->flags &= ~(LineBeforeStarts|LineBeforeEnds|LineBeforeHorizontal);
- if (y_prev < y_curr)
- v0->flags |= LineBeforeEnds;
- else if (y_prev > y_curr)
- v0->flags |= LineBeforeStarts;
- else
- v0->flags |= LineBeforeHorizontal;
- if ((v0->flags & (LineBeforeStarts|LineAfterStarts))
- && !(v0->flags & (LineAfterEnds|LineBeforeEnds)))
- *maxActiveEdges += 2;
- break;
- }
-
- if (y_prev < y_curr)
- v->flags |= LineBeforeEnds;
- else if (y_prev > y_curr)
- v->flags |= LineBeforeStarts;
- else
- v->flags |= LineBeforeHorizontal;
-
-
- if (y_curr < y_next)
- v->flags |= LineAfterStarts;
- else if (y_curr > y_next)
- v->flags |= LineAfterEnds;
- else
- v->flags |= LineAfterHorizontal;
- // ### could probably get better limit by looping over sorted list and counting down on ending edges
- if ((v->flags & (LineBeforeStarts|LineAfterStarts))
- && !(v->flags & (LineAfterEnds|LineBeforeEnds)))
- *maxActiveEdges += 2;
- y_prev = y_curr;
- ++v;
- ++vv;
- ++j;
- ++i;
- }
- vertices.nPoints = j;
-
- QDEBUG() << "maxActiveEdges=" << *maxActiveEdges;
- vv = vertices.sorted;
- std::sort(vv, vv + vertices.nPoints, compareVertex);
-
- return QRectF(xmin, ymin, xmax-xmin, ymax-ymin);
-}
-
-struct QCoincidingEdge {
- QTessellatorPrivate::Vertex *start;
- QTessellatorPrivate::Vertex *end;
- bool used;
- bool before;
-
- inline bool operator<(const QCoincidingEdge &e2) const
- {
- return end->y == e2.end->y ? end->x < e2.end->x : end->y < e2.end->y;
- }
-};
-
-static void cancelEdges(QCoincidingEdge &e1, QCoincidingEdge &e2)
-{
- if (e1.before) {
- e1.start->flags &= ~(LineBeforeStarts|LineBeforeHorizontal);
- e1.end->flags &= ~(LineAfterEnds|LineAfterHorizontal);
- } else {
- e1.start->flags &= ~(LineAfterStarts|LineAfterHorizontal);
- e1.end->flags &= ~(LineBeforeEnds|LineBeforeHorizontal);
- }
- if (e2.before) {
- e2.start->flags &= ~(LineBeforeStarts|LineBeforeHorizontal);
- e2.end->flags &= ~(LineAfterEnds|LineAfterHorizontal);
- } else {
- e2.start->flags &= ~(LineAfterStarts|LineAfterHorizontal);
- e2.end->flags &= ~(LineBeforeEnds|LineBeforeHorizontal);
- }
- e1.used = e2.used = true;
-}
-
-void QTessellatorPrivate::cancelCoincidingEdges()
-{
- Vertex **vv = vertices.sorted;
-
- QCoincidingEdge *tl = nullptr;
- int tlSize = 0;
-
- for (int i = 0; i < vertices.nPoints - 1; ++i) {
- Vertex *v = vv[i];
- int testListSize = 0;
- while (i < vertices.nPoints - 1) {
- Vertex *n = vv[i];
- if (v->x != n->x || v->y != n->y)
- break;
-
- if (testListSize > tlSize - 2) {
- tlSize = qMax(tlSize*2, 16);
- tl = q_check_ptr((QCoincidingEdge *)realloc(tl, tlSize*sizeof(QCoincidingEdge)));
- }
- if (n->flags & (LineBeforeStarts|LineBeforeHorizontal)) {
- tl[testListSize].start = n;
- tl[testListSize].end = vertices.prev(n);
- tl[testListSize].used = false;
- tl[testListSize].before = true;
- ++testListSize;
- }
- if (n->flags & (LineAfterStarts|LineAfterHorizontal)) {
- tl[testListSize].start = n;
- tl[testListSize].end = vertices.next(n);
- tl[testListSize].used = false;
- tl[testListSize].before = false;
- ++testListSize;
- }
- ++i;
- }
- if (!testListSize)
- continue;
-
- std::sort(tl, tl + testListSize);
-
-QT_WARNING_PUSH
-QT_WARNING_DISABLE_CLANG("-Wfor-loop-analysis")
- for (int j = 0; j < testListSize; ++j) {
- if (tl[j].used)
- continue;
-
- for (int k = j + 1; k < testListSize; ++k) {
- if (tl[j].end->x != tl[k].end->x
- || tl[j].end->y != tl[k].end->y
- || tl[k].used)
- break;
-
- if (!winding || tl[j].before != tl[k].before) {
- cancelEdges(tl[j], tl[k]);
- break;
- }
- ++k;
- }
- ++j;
- }
-QT_WARNING_POP
- }
- free(tl);
-}
-
-
-void QTessellatorPrivate::emitEdges(QTessellator *tessellator)
-{
- //QDEBUG() << "TRAPS:";
- if (!scanline.old_size)
- return;
-
- // emit edges
- if (winding) {
- // winding fill rule
- int w = 0;
-
- scanline.old[0]->y_left = y;
-
- for (int i = 0; i < scanline.old_size - 1; ++i) {
- Edge *left = scanline.old[i];
- Edge *right = scanline.old[i+1];
- w += left->winding;
-// qDebug() << "i=" << i << "edge->winding=" << left->winding << "winding=" << winding;
- if (w == 0) {
- left->y_right = y;
- right->y_left = y;
- } else if (!emit_clever || left->mark || right->mark) {
- Q27Dot5 top = qMax(left->y_right, right->y_left);
- if (top != y) {
- QTessellator::Trapezoid trap;
- fillTrapezoid(top, y, left->edge, right->edge, vertices, &trap);
- tessellator->addTrap(trap);
-// QDEBUG() << " top=" << Q27Dot5ToDouble(top) << "left=" << left->edge << "right=" << right->edge;
- }
- right->y_left = y;
- left->y_right = y;
- }
- left->mark = false;
- }
- if (scanline.old[scanline.old_size - 1]->mark) {
- scanline.old[scanline.old_size - 1]->y_right = y;
- scanline.old[scanline.old_size - 1]->mark = false;
- }
- } else {
- // odd-even fill rule
- for (int i = 0; i < scanline.old_size; i += 2) {
- Edge *left = scanline.old[i];
- Edge *right = scanline.old[i+1];
- if (!emit_clever || left->mark || right->mark) {
- Q27Dot5 top = qMax(left->y_right, right->y_left);
- if (top != y) {
- QTessellator::Trapezoid trap;
- fillTrapezoid(top, y, left->edge, right->edge, vertices, &trap);
- tessellator->addTrap(trap);
- }
-// QDEBUG() << " top=" << Q27Dot5ToDouble(top) << "left=" << left->edge << "right=" << right->edge;
- left->y_left = y;
- left->y_right = y;
- right->y_left = y;
- right->y_right = y;
- left->mark = right->mark = false;
- }
- }
- }
-}
-
-
-void QTessellatorPrivate::processIntersections()
-{
- QDEBUG() << "PROCESS INTERSECTIONS";
- // process intersections
- while (!intersections.isEmpty()) {
- Intersections::iterator it = intersections.begin();
- if (it.key().y != y)
- break;
-
- // swap edges
- QDEBUG() << " swapping intersecting edges ";
- int min = scanline.size;
- int max = 0;
- Q27Dot5 xmin = INT_MAX;
- Q27Dot5 xmax = INT_MIN;
- int num = 0;
- while (1) {
- const Intersection i = it.key();
- int next = it->next;
-
- int edgePos = scanline.findEdge(i.edge);
- if (edgePos >= 0) {
- ++num;
- min = qMin(edgePos, min);
- max = qMax(edgePos, max);
- Edge *edge = scanline.edges[edgePos];
- xmin = qMin(xmin, edge->positionAt(y));
- xmax = qMax(xmax, edge->positionAt(y));
- }
- Intersection key;
- key.y = y;
- key.edge = next;
- it = intersections.find(key);
- intersections.remove(i);
- if (it == intersections.end())
- break;
- }
- if (num < 2)
- continue;
-
- Q_ASSERT(min != max);
- QDEBUG() << "sorting between" << min << "and" << max << "xpos=" << xmin << xmax;
- while (min > 0 && scanline.edges[min - 1]->positionAt(y) >= xmin) {
- QDEBUG() << " adding edge on left";
- --min;
- }
- while (max < scanline.size - 1 && scanline.edges[max + 1]->positionAt(y) <= xmax) {
- QDEBUG() << " adding edge on right";
- ++max;
- }
-
- std::sort(scanline.edges + min, scanline.edges + max + 1, EdgeSorter(y));
-#ifdef DEBUG
- for (int i = min; i <= max; ++i)
- QDEBUG() << " " << scanline.edges[i]->edge << "at pos" << i;
-#endif
- for (int i = min; i <= max; ++i) {
- Edge *edge = scanline.edges[i];
- edge->intersect_left = true;
- edge->intersect_right = true;
- edge->mark = true;
- }
- }
-}
-
-void QTessellatorPrivate::removeEdges()
-{
- int cv = currentVertex;
- while (cv < vertices.nPoints) {
- const Vertex *v = vertices.sorted[cv];
- if (v->y > y)
- break;
- if (v->flags & LineBeforeEnds) {
- QDEBUG() << " removing edge" << vertices.prevPos(v);
- int pos = scanline.findEdge(vertices.prevPos(v));
- if (pos == -1)
- continue;
- scanline.edges[pos]->mark = true;
- if (pos > 0)
- scanline.edges[pos - 1]->intersect_right = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->intersect_left = true;
- scanline.removeAt(pos);
- }
- if (v->flags & LineAfterEnds) {
- QDEBUG() << " removing edge" << vertices.position(v);
- int pos = scanline.findEdge(vertices.position(v));
- if (pos == -1)
- continue;
- scanline.edges[pos]->mark = true;
- if (pos > 0)
- scanline.edges[pos - 1]->intersect_right = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->intersect_left = true;
- scanline.removeAt(pos);
- }
- ++cv;
- }
-}
-
-void QTessellatorPrivate::addEdges()
-{
- while (currentVertex < vertices.nPoints) {
- const Vertex *v = vertices.sorted[currentVertex];
- if (v->y > y)
- break;
- if (v->flags & LineBeforeStarts) {
- // add new edge
- int start = vertices.prevPos(v);
- Edge e(vertices, start);
- int pos = scanline.findEdgePosition(e);
- QDEBUG() << " adding edge" << start << "at position" << pos;
- scanline.insert(pos, e);
- if (!mark_clever || !(v->flags & LineAfterEnds)) {
- if (pos > 0)
- scanline.edges[pos - 1]->mark = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->mark = true;
- }
- }
- if (v->flags & LineAfterStarts) {
- Edge e(vertices, vertices.position(v));
- int pos = scanline.findEdgePosition(e);
- QDEBUG() << " adding edge" << vertices.position(v) << "at position" << pos;
- scanline.insert(pos, e);
- if (!mark_clever || !(v->flags & LineBeforeEnds)) {
- if (pos > 0)
- scanline.edges[pos - 1]->mark = true;
- if (pos < scanline.size - 1)
- scanline.edges[pos + 1]->mark = true;
- }
- }
- if (v->flags & LineAfterHorizontal) {
- int pos1 = scanline.findEdgePosition(v->x, v->y);
- const Vertex *next = vertices.next(v);
- Q_ASSERT(v->y == next->y);
- int pos2 = scanline.findEdgePosition(next->x, next->y);
- if (pos2 < pos1)
- qSwap(pos1, pos2);
- if (pos1 > 0)
- --pos1;
- if (pos2 == scanline.size)
- --pos2;
- //QDEBUG() << "marking horizontal edge from " << pos1 << "to" << pos2;
- scanline.markEdges(pos1, pos2);
- }
- ++currentVertex;
- }
-}
-
-#ifdef DEBUG
-static void checkLinkChain(const QTessellatorPrivate::Intersections &intersections,
- QTessellatorPrivate::Intersection i)
-{
-// qDebug() << " Link chain: ";
- int end = i.edge;
- while (1) {
- QTessellatorPrivate::IntersectionLink l = intersections.value(i);
-// qDebug() << " " << i.edge << "next=" << l.next << "prev=" << l.prev;
- if (l.next == end)
- break;
- Q_ASSERT(l.next != -1);
- Q_ASSERT(l.prev != -1);
-
- QTessellatorPrivate::Intersection i2 = i;
- i2.edge = l.next;
- QTessellatorPrivate::IntersectionLink l2 = intersections.value(i2);
-
- Q_ASSERT(l2.next != -1);
- Q_ASSERT(l2.prev != -1);
- Q_ASSERT(l.next == i2.edge);
- Q_ASSERT(l2.prev == i.edge);
- i = i2;
- }
-}
-#endif
-
-bool QTessellatorPrivate::edgeInChain(Intersection i, int edge)
-{
- int end = i.edge;
- while (1) {
- if (i.edge == edge)
- return true;
- IntersectionLink l = intersections.value(i);
- if (l.next == end)
- break;
- Q_ASSERT(l.next != -1);
- Q_ASSERT(l.prev != -1);
-
- Intersection i2 = i;
- i2.edge = l.next;
-
-#ifndef QT_NO_DEBUG
- IntersectionLink l2 = intersections.value(i2);
- Q_ASSERT(l2.next != -1);
- Q_ASSERT(l2.prev != -1);
- Q_ASSERT(l.next == i2.edge);
- Q_ASSERT(l2.prev == i.edge);
-#endif
- i = i2;
- }
- return false;
-}
-
-
-void QTessellatorPrivate::addIntersection(const Edge *e1, const Edge *e2)
-{
- const IntersectionLink emptyLink = {-1, -1};
-
- int next = vertices.nextPos(vertices[e1->edge]);
- if (e2->edge == next)
- return;
- int prev = vertices.prevPos(vertices[e1->edge]);
- if (e2->edge == prev)
- return;
-
- Q27Dot5 yi;
- bool det_positive;
- bool isect = e1->intersect(*e2, &yi, &det_positive);
- QDEBUG("checking edges %d and %d", e1->edge, e2->edge);
- if (!isect) {
- QDEBUG() << " no intersection";
- return;
- }
-
- // don't emit an intersection if it's at the start of a line segment or above us
- if (yi <= y) {
- if (!det_positive)
- return;
- QDEBUG() << " ----->>>>>> WRONG ORDER!";
- yi = y;
- }
- QDEBUG() << " between edges " << e1->edge << "and" << e2->edge << "at point ("
- << Q27Dot5ToDouble(yi) << ')';
-
- Intersection i1;
- i1.y = yi;
- i1.edge = e1->edge;
- IntersectionLink link1 = intersections.value(i1, emptyLink);
- Intersection i2;
- i2.y = yi;
- i2.edge = e2->edge;
- IntersectionLink link2 = intersections.value(i2, emptyLink);
-
- // new pair of edges
- if (link1.next == -1 && link2.next == -1) {
- link1.next = link1.prev = i2.edge;
- link2.next = link2.prev = i1.edge;
- } else if (link1.next == i2.edge || link1.prev == i2.edge
- || link2.next == i1.edge || link2.prev == i1.edge) {
-#ifdef DEBUG
- checkLinkChain(intersections, i1);
- checkLinkChain(intersections, i2);
- Q_ASSERT(edgeInChain(i1, i2.edge));
-#endif
- return;
- } else if (link1.next == -1 || link2.next == -1) {
- if (link2.next == -1) {
- qSwap(i1, i2);
- qSwap(link1, link2);
- }
- Q_ASSERT(link1.next == -1);
-#ifdef DEBUG
- checkLinkChain(intersections, i2);
-#endif
- // only i2 in list
- link1.next = i2.edge;
- link1.prev = link2.prev;
- link2.prev = i1.edge;
- Intersection other;
- other.y = yi;
- other.edge = link1.prev;
- IntersectionLink link = intersections.value(other, emptyLink);
- Q_ASSERT(link.next == i2.edge);
- Q_ASSERT(link.prev != -1);
- link.next = i1.edge;
- intersections.insert(other, link);
- } else {
- bool connected = edgeInChain(i1, i2.edge);
- if (connected)
- return;
-#ifdef DEBUG
- checkLinkChain(intersections, i1);
- checkLinkChain(intersections, i2);
-#endif
- // both already in some list. Have to make sure they are connected
- // this can be done by cutting open the ring(s) after the two eges and
- // connecting them again
- Intersection other1;
- other1.y = yi;
- other1.edge = link1.next;
- IntersectionLink linko1 = intersections.value(other1, emptyLink);
- Intersection other2;
- other2.y = yi;
- other2.edge = link2.next;
- IntersectionLink linko2 = intersections.value(other2, emptyLink);
-
- linko1.prev = i2.edge;
- link2.next = other1.edge;
-
- linko2.prev = i1.edge;
- link1.next = other2.edge;
- intersections.insert(other1, linko1);
- intersections.insert(other2, linko2);
- }
- intersections.insert(i1, link1);
- intersections.insert(i2, link2);
-#ifdef DEBUG
- checkLinkChain(intersections, i1);
- checkLinkChain(intersections, i2);
- Q_ASSERT(edgeInChain(i1, i2.edge));
-#endif
- return;
-
-}
-
-
-void QTessellatorPrivate::addIntersections()
-{
- if (scanline.size) {
- QDEBUG() << "INTERSECTIONS";
- // check marked edges for intersections
-#ifdef DEBUG
- for (int i = 0; i < scanline.size; ++i) {
- Edge *e = scanline.edges[i];
- QDEBUG() << " " << i << e->edge << "isect=(" << e->intersect_left << e->intersect_right
- << ')';
- }
-#endif
-
- for (int i = 0; i < scanline.size - 1; ++i) {
- Edge *e1 = scanline.edges[i];
- Edge *e2 = scanline.edges[i + 1];
- // check for intersection
- if (e1->intersect_right || e2->intersect_left)
- addIntersection(e1, e2);
- }
- }
-#if 0
- if (intersections.constBegin().key().y == y) {
- QDEBUG() << "----------------> intersection on same line";
- scanline.clearMarks();
- scanline.processIntersections(y, &intersections);
- goto redo;
- }
-#endif
-}
-
-
-QTessellator::QTessellator()
-{
- d = new QTessellatorPrivate;
-}
-
-QTessellator::~QTessellator()
-{
- delete d;
-}
-
-void QTessellator::setWinding(bool w)
-{
- d->winding = w;
-}
-
-
-QRectF QTessellator::tessellate(const QPointF *points, int nPoints)
-{
- Q_ASSERT(points[0] == points[nPoints-1]);
- --nPoints;
-
-#ifdef DEBUG
- QDEBUG()<< "POINTS:";
- for (int i = 0; i < nPoints; ++i) {
- QDEBUG() << points[i];
- }
-#endif
-
- // collect edges and calculate bounds
- d->vertices.nPoints = nPoints;
- d->vertices.init(nPoints);
-
- int maxActiveEdges = 0;
- QRectF br = d->collectAndSortVertices(points, &maxActiveEdges);
- d->cancelCoincidingEdges();
-
-#ifdef DEBUG
- QDEBUG() << "nPoints = " << nPoints << "using " << d->vertices.nPoints;
- QDEBUG()<< "VERTICES:";
- for (int i = 0; i < d->vertices.nPoints; ++i) {
- QDEBUG() << " " << i << ": "
- << "point=" << d->vertices.position(d->vertices.sorted[i])
- << "flags=" << d->vertices.sorted[i]->flags
- << "pos=(" << Q27Dot5ToDouble(d->vertices.sorted[i]->x) << '/'
- << Q27Dot5ToDouble(d->vertices.sorted[i]->y) << ')';
- }
-#endif
-
- d->scanline.init(maxActiveEdges);
- d->y = INT_MIN/256;
- d->currentVertex = 0;
-
- while (d->currentVertex < d->vertices.nPoints) {
- d->scanline.clearMarks();
-
- d->y = d->vertices.sorted[d->currentVertex]->y;
- if (!d->intersections.isEmpty())
- d->y = qMin(d->y, d->intersections.constBegin().key().y);
-
- QDEBUG()<< "===== SCANLINE: y =" << Q27Dot5ToDouble(d->y) << " =====";
-
- d->scanline.prepareLine();
- d->processIntersections();
- d->removeEdges();
- d->addEdges();
- d->addIntersections();
- d->emitEdges(this);
- d->scanline.lineDone();
-
-#ifdef DEBUG
- QDEBUG()<< "===== edges:";
- for (int i = 0; i < d->scanline.size; ++i) {
- QDEBUG() << " " << d->scanline.edges[i]->edge
- << "p0= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v0->x)
- << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v0->y)
- << ") p1= (" << Q27Dot5ToDouble(d->scanline.edges[i]->v1->x)
- << '/' << Q27Dot5ToDouble(d->scanline.edges[i]->v1->y) << ')'
- << "x=" << Q27Dot5ToDouble(d->scanline.edges[i]->positionAt(d->y))
- << "isLeftOfNext="
- << ((i < d->scanline.size - 1)
- ? d->scanline.edges[i]->isLeftOf(*d->scanline.edges[i+1], d->y)
- : true);
- }
-#endif
-}
-
- d->scanline.done();
- d->intersections.clear();
- return br;
-}
-
-// tessellates the given convex polygon
-void QTessellator::tessellateConvex(const QPointF *points, int nPoints)
-{
- Q_ASSERT(points[0] == points[nPoints-1]);
- --nPoints;
-
- d->vertices.nPoints = nPoints;
- d->vertices.init(nPoints);
-
- for (int i = 0; i < nPoints; ++i) {
- d->vertices[i]->x = FloatToQ27Dot5(points[i].x());
- d->vertices[i]->y = FloatToQ27Dot5(points[i].y());
- }
-
- int left = 0, right = 0;
-
- int top = 0;
- for (int i = 1; i < nPoints; ++i) {
- if (d->vertices[i]->y < d->vertices[top]->y)
- top = i;
- }
-
- left = (top + nPoints - 1) % nPoints;
- right = (top + 1) % nPoints;
-
- while (d->vertices[left]->x == d->vertices[top]->x && d->vertices[left]->y == d->vertices[top]->y && left != right)
- left = (left + nPoints - 1) % nPoints;
-
- while (d->vertices[right]->x == d->vertices[top]->x && d->vertices[right]->y == d->vertices[top]->y && left != right)
- right = (right + 1) % nPoints;
-
- if (left == right)
- return;
-
- int dir = 1;
-
- Vertex dLeft = { d->vertices[top]->x - d->vertices[left]->x,
- d->vertices[top]->y - d->vertices[left]->y };
-
- Vertex dRight = { d->vertices[right]->x - d->vertices[top]->x,
- d->vertices[right]->y - d->vertices[top]->y };
-
- Q27Dot5 cross = dLeft.x * dRight.y - dLeft.y * dRight.x;
-
- // flip direction if polygon is clockwise
- if (cross < 0 || (cross == 0 && dLeft.x > 0)) {
- qSwap(left, right);
- dir = -1;
- }
-
- Vertex *lastLeft = d->vertices[top];
- Vertex *lastRight = d->vertices[top];
-
- QTessellator::Trapezoid trap;
-
- while (lastLeft->y == d->vertices[left]->y && left != right) {
- lastLeft = d->vertices[left];
- left = (left + nPoints - dir) % nPoints;
- }
-
- while (lastRight->y == d->vertices[right]->y && left != right) {
- lastRight = d->vertices[right];
- right = (right + nPoints + dir) % nPoints;
- }
-
- while (true) {
- trap.top = qMax(lastRight->y, lastLeft->y);
- trap.bottom = qMin(d->vertices[left]->y, d->vertices[right]->y);
- trap.topLeft = lastLeft;
- trap.topRight = lastRight;
- trap.bottomLeft = d->vertices[left];
- trap.bottomRight = d->vertices[right];
-
- if (trap.bottom > trap.top)
- addTrap(trap);
-
- if (left == right)
- break;
-
- if (d->vertices[right]->y < d->vertices[left]->y) {
- do {
- lastRight = d->vertices[right];
- right = (right + nPoints + dir) % nPoints;
- }
- while (lastRight->y == d->vertices[right]->y && left != right);
- } else {
- do {
- lastLeft = d->vertices[left];
- left = (left + nPoints - dir) % nPoints;
- }
- while (lastLeft->y == d->vertices[left]->y && left != right);
- }
- }
-}
-
-// tessellates the stroke of the line from a_ to b_ with the given width and a flat cap
-void QTessellator::tessellateRect(const QPointF &a_, const QPointF &b_, qreal width)
-{
- Vertex a = { FloatToQ27Dot5(a_.x()), FloatToQ27Dot5(a_.y()) };
- Vertex b = { FloatToQ27Dot5(b_.x()), FloatToQ27Dot5(b_.y()) };
-
- QPointF pa = a_, pb = b_;
-
- if (a.y > b.y) {
- qSwap(a, b);
- qSwap(pa, pb);
- }
-
- Vertex delta = { b.x - a.x, b.y - a.y };
-
- if (delta.x == 0 && delta.y == 0)
- return;
-
- qreal hw = 0.5 * width;
-
- if (delta.x == 0) {
- Q27Dot5 halfWidth = FloatToQ27Dot5(hw);
-
- if (halfWidth == 0)
- return;
-
- Vertex topLeft = { a.x - halfWidth, a.y };
- Vertex topRight = { a.x + halfWidth, a.y };
- Vertex bottomLeft = { a.x - halfWidth, b.y };
- Vertex bottomRight = { a.x + halfWidth, b.y };
-
- QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight };
- addTrap(trap);
- } else if (delta.y == 0) {
- Q27Dot5 halfWidth = FloatToQ27Dot5(hw);
-
- if (halfWidth == 0)
- return;
-
- if (a.x > b.x)
- qSwap(a.x, b.x);
-
- Vertex topLeft = { a.x, a.y - halfWidth };
- Vertex topRight = { b.x, a.y - halfWidth };
- Vertex bottomLeft = { a.x, a.y + halfWidth };
- Vertex bottomRight = { b.x, a.y + halfWidth };
-
- QTessellator::Trapezoid trap = { topLeft.y, bottomLeft.y, &topLeft, &bottomLeft, &topRight, &bottomRight };
- addTrap(trap);
- } else {
- QPointF perp(pb.y() - pa.y(), pa.x() - pb.x());
- qreal length = qSqrt(perp.x() * perp.x() + perp.y() * perp.y());
-
- if (qFuzzyIsNull(length))
- return;
-
- // need the half of the width
- perp *= hw / length;
-
- QPointF pta = pa + perp;
- QPointF ptb = pa - perp;
- QPointF ptc = pb - perp;
- QPointF ptd = pb + perp;
-
- Vertex ta = { FloatToQ27Dot5(pta.x()), FloatToQ27Dot5(pta.y()) };
- Vertex tb = { FloatToQ27Dot5(ptb.x()), FloatToQ27Dot5(ptb.y()) };
- Vertex tc = { FloatToQ27Dot5(ptc.x()), FloatToQ27Dot5(ptc.y()) };
- Vertex td = { FloatToQ27Dot5(ptd.x()), FloatToQ27Dot5(ptd.y()) };
-
- if (ta.y < tb.y) {
- if (tb.y < td.y) {
- QTessellator::Trapezoid top = { ta.y, tb.y, &ta, &tb, &ta, &td };
- QTessellator::Trapezoid bottom = { td.y, tc.y, &tb, &tc, &td, &tc };
- addTrap(top);
- addTrap(bottom);
-
- QTessellator::Trapezoid middle = { tb.y, td.y, &tb, &tc, &ta, &td };
- addTrap(middle);
- } else {
- QTessellator::Trapezoid top = { ta.y, td.y, &ta, &tb, &ta, &td };
- QTessellator::Trapezoid bottom = { tb.y, tc.y, &tb, &tc, &td, &tc };
- addTrap(top);
- addTrap(bottom);
-
- if (tb.y != td.y) {
- QTessellator::Trapezoid middle = { td.y, tb.y, &ta, &tb, &td, &tc };
- addTrap(middle);
- }
- }
- } else {
- if (ta.y < tc.y) {
- QTessellator::Trapezoid top = { tb.y, ta.y, &tb, &tc, &tb, &ta };
- QTessellator::Trapezoid bottom = { tc.y, td.y, &tc, &td, &ta, &td };
- addTrap(top);
- addTrap(bottom);
-
- QTessellator::Trapezoid middle = { ta.y, tc.y, &tb, &tc, &ta, &td };
- addTrap(middle);
- } else {
- QTessellator::Trapezoid top = { tb.y, tc.y, &tb, &tc, &tb, &ta };
- QTessellator::Trapezoid bottom = { ta.y, td.y, &tc, &td, &ta, &td };
- addTrap(top);
- addTrap(bottom);
-
- if (ta.y != tc.y) {
- QTessellator::Trapezoid middle = { tc.y, ta.y, &tc, &td, &tb, &ta };
- addTrap(middle);
- }
- }
- }
- }
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qtessellator_p.h b/src/plugins/platforms/xcb/nativepainting/qtessellator_p.h
deleted file mode 100644
index ba1d3a971a3..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qtessellator_p.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-#include <QPoint>
-#include <QRect>
-
-QT_BEGIN_NAMESPACE
-
-class QTessellatorPrivate;
-
-typedef int Q27Dot5;
-#define Q27Dot5ToDouble(i) ((i)/32.)
-#define FloatToQ27Dot5(i) (int)((i) * 32)
-#define IntToQ27Dot5(i) ((i) << 5)
-#define Q27Dot5ToXFixed(i) ((i) << 11)
-#define Q27Dot5Factor 32
-
-class QTessellator {
-public:
- QTessellator();
- virtual ~QTessellator();
-
- QRectF tessellate(const QPointF *points, int nPoints);
- void tessellateConvex(const QPointF *points, int nPoints);
- void tessellateRect(const QPointF &a, const QPointF &b, qreal width);
-
- void setWinding(bool w);
-
- struct Vertex {
- Q27Dot5 x;
- Q27Dot5 y;
- };
- struct Trapezoid {
- Q27Dot5 top;
- Q27Dot5 bottom;
- const Vertex *topLeft;
- const Vertex *bottomLeft;
- const Vertex *topRight;
- const Vertex *bottomRight;
- };
- virtual void addTrap(const Trapezoid &trap) = 0;
-
-private:
- friend class QTessellatorPrivate;
- QTessellatorPrivate *d;
-};
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp b/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp
deleted file mode 100644
index 23155ef2e62..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.cpp
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#include <QtCore/qrandom.h>
-
-#include "qxcbconnection.h"
-#include "qcolormap_x11_p.h"
-#include "qxcbnativepainting.h"
-#include "qt_x11_p.h"
-
-QT_BEGIN_NAMESPACE
-
-QXcbX11Data *qt_x11Data = nullptr;
-
-void qt_xcb_native_x11_info_init(QXcbConnection *conn)
-{
- qt_x11Data = new QXcbX11Data;
- X11->display = static_cast<Display *>(conn->xlib_display());
- X11->defaultScreen = DefaultScreen(X11->display);
- X11->screenCount = ScreenCount(X11->display);
-
- X11->screens = new QX11InfoData[X11->screenCount];
- X11->argbVisuals = new Visual *[X11->screenCount];
- X11->argbColormaps = new Colormap[X11->screenCount];
-
- for (int s = 0; s < X11->screenCount; s++) {
- QX11InfoData *screen = X11->screens + s;
- //screen->ref = 1; // ensures it doesn't get deleted
- screen->screen = s;
-
- int widthMM = DisplayWidthMM(X11->display, s);
- if (widthMM != 0) {
- screen->dpiX = (DisplayWidth(X11->display, s) * 254 + widthMM * 5) / (widthMM * 10);
- } else {
- screen->dpiX = 72;
- }
-
- int heightMM = DisplayHeightMM(X11->display, s);
- if (heightMM != 0) {
- screen->dpiY = (DisplayHeight(X11->display, s) * 254 + heightMM * 5) / (heightMM * 10);
- } else {
- screen->dpiY = 72;
- }
-
- X11->argbVisuals[s] = 0;
- X11->argbColormaps[s] = 0;
- }
-
- X11->use_xrender = conn->hasXRender() && !qEnvironmentVariableIsSet("QT_XCB_NATIVE_PAINTING_NO_XRENDER");
-
-#if QT_CONFIG(xrender)
- memset(X11->solid_fills, 0, sizeof(X11->solid_fills));
- for (int i = 0; i < X11->solid_fill_count; ++i)
- X11->solid_fills[i].screen = -1;
- memset(X11->pattern_fills, 0, sizeof(X11->pattern_fills));
- for (int i = 0; i < X11->pattern_fill_count; ++i)
- X11->pattern_fills[i].screen = -1;
-#endif
-
- QXcbColormap::initialize();
-
-#if QT_CONFIG(xrender)
- if (X11->use_xrender) {
- // XRender is supported, let's see if we have a PictFormat for the
- // default visual
- XRenderPictFormat *format =
- XRenderFindVisualFormat(X11->display,
- (Visual *) QXcbX11Info::appVisual(X11->defaultScreen));
-
- if (!format) {
- X11->use_xrender = false;
- }
- }
-#endif // QT_CONFIG(xrender)
-}
-
-QList<XRectangle> qt_region_to_xrectangles(const QRegion &r)
-{
- const int numRects = r.rectCount();
- const auto input = r.begin();
- QList<XRectangle> output(numRects);
- for (int i = 0; i < numRects; ++i) {
- const QRect &in = input[i];
- XRectangle &out = output[i];
- out.x = qMax(SHRT_MIN, in.x());
- out.y = qMax(SHRT_MIN, in.y());
- out.width = qMin((int)USHRT_MAX, in.width());
- out.height = qMin((int)USHRT_MAX, in.height());
- }
- return output;
-}
-
-class QXcbX11InfoData : public QSharedData, public QX11InfoData
-{};
-
-QXcbX11Info::QXcbX11Info()
- : d(nullptr)
-{}
-
-QXcbX11Info::~QXcbX11Info()
-{}
-
-QXcbX11Info::QXcbX11Info(const QXcbX11Info &other)
- : d(other.d)
-{}
-
-QXcbX11Info &QXcbX11Info::operator=(const QXcbX11Info &other)
-{
- d = other.d;
- return *this;
-}
-
-QXcbX11Info QXcbX11Info::fromScreen(int screen)
-{
- QXcbX11InfoData *xd = new QXcbX11InfoData;
- xd->screen = screen;
- xd->depth = QXcbX11Info::appDepth(screen);
- xd->cells = QXcbX11Info::appCells(screen);
- xd->colormap = QXcbX11Info::appColormap(screen);
- xd->defaultColormap = QXcbX11Info::appDefaultColormap(screen);
- xd->visual = (Visual *)QXcbX11Info::appVisual(screen);
- xd->defaultVisual = QXcbX11Info::appDefaultVisual(screen);
-
- QXcbX11Info info;
- info.d = xd;
- return info;
-}
-
-void QXcbX11Info::setDepth(int depth)
-{
- if (!d)
- *this = fromScreen(appScreen());
-
- d->depth = depth;
-}
-
-Display *QXcbX11Info::display()
-{
- return X11 ? X11->display : 0;
-}
-
-int QXcbX11Info::screen() const
-{
- return d ? d->screen : QXcbX11Info::appScreen();
-}
-
-int QXcbX11Info::depth() const
-{
- return d ? d->depth : QXcbX11Info::appDepth();
-}
-
-Colormap QXcbX11Info::colormap() const
-{
- return d ? d->colormap : QXcbX11Info::appColormap();
-}
-
-void *QXcbX11Info::visual() const
-{
- return d ? d->visual : QXcbX11Info::appVisual();
-}
-
-void QXcbX11Info::setVisual(void *visual)
-{
- if (!d)
- *this = fromScreen(appScreen());
-
- d->visual = (Visual *) visual;
-}
-
-int QXcbX11Info::appScreen()
-{
- return X11 ? X11->defaultScreen : 0;
-}
-
-int QXcbX11Info::appDepth(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].depth : 32;
-}
-
-int QXcbX11Info::appCells(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].cells : 0;
-}
-
-Colormap QXcbX11Info::appColormap(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].colormap : 0;
-}
-
-void *QXcbX11Info::appVisual(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].visual : 0;
-}
-
-Window QXcbX11Info::appRootWindow(int screen)
-{
- return X11 ? RootWindow(X11->display, screen == -1 ? X11->defaultScreen : screen) : 0;
-}
-
-bool QXcbX11Info::appDefaultColormap(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].defaultColormap : true;
-}
-
-bool QXcbX11Info::appDefaultVisual(int screen)
-{
- return X11 ? X11->screens[screen == -1 ? X11->defaultScreen : screen].defaultVisual : true;
-}
-
-int QXcbX11Info::appDpiX(int screen)
-{
- if (!X11)
- return 75;
- if (screen < 0)
- screen = X11->defaultScreen;
- if (screen > X11->screenCount)
- return 0;
- return X11->screens[screen].dpiX;
-}
-
-int QXcbX11Info::appDpiY(int screen)
-{
- if (!X11)
- return 75;
- if (screen < 0)
- screen = X11->defaultScreen;
- if (screen > X11->screenCount)
- return 0;
- return X11->screens[screen].dpiY;
-}
-
-#if QT_CONFIG(xrender)
-Picture QXcbX11Data::getSolidFill(int screen, const QColor &c)
-{
- if (!X11->use_xrender)
- return XNone;
-
- XRenderColor color = preMultiply(c);
- for (int i = 0; i < X11->solid_fill_count; ++i) {
- if (X11->solid_fills[i].screen == screen
- && X11->solid_fills[i].color.alpha == color.alpha
- && X11->solid_fills[i].color.red == color.red
- && X11->solid_fills[i].color.green == color.green
- && X11->solid_fills[i].color.blue == color.blue)
- return X11->solid_fills[i].picture;
- }
- // none found, replace one
- int i = QRandomGenerator::global()->generate() % 16;
-
- if (X11->solid_fills[i].screen != screen && X11->solid_fills[i].picture) {
- XRenderFreePicture (X11->display, X11->solid_fills[i].picture);
- X11->solid_fills[i].picture = 0;
- }
-
- if (!X11->solid_fills[i].picture) {
- Pixmap pixmap = XCreatePixmap (X11->display, RootWindow (X11->display, screen), 1, 1, 32);
- XRenderPictureAttributes attrs;
- attrs.repeat = True;
- X11->solid_fills[i].picture = XRenderCreatePicture (X11->display, pixmap,
- XRenderFindStandardFormat(X11->display, PictStandardARGB32),
- CPRepeat, &attrs);
- XFreePixmap (X11->display, pixmap);
- }
-
- X11->solid_fills[i].color = color;
- X11->solid_fills[i].screen = screen;
- XRenderFillRectangle (X11->display, PictOpSrc, X11->solid_fills[i].picture, &color, 0, 0, 1, 1);
- return X11->solid_fills[i].picture;
-}
-
-XRenderColor QXcbX11Data::preMultiply(const QColor &c)
-{
- XRenderColor color;
- const uint A = c.alpha(),
- R = c.red(),
- G = c.green(),
- B = c.blue();
- color.alpha = (A | A << 8);
- color.red = (R | R << 8) * color.alpha / 0x10000;
- color.green = (G | G << 8) * color.alpha / 0x10000;
- color.blue = (B | B << 8) * color.alpha / 0x10000;
- return color;
-}
-#endif // QT_CONFIG(xrender)
-
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.h b/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.h
deleted file mode 100644
index dac9b101c43..00000000000
--- a/src/plugins/platforms/xcb/nativepainting/qxcbnativepainting.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright (C) 2018 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
-// Qt-Security score:significant reason:default
-
-#pragma once
-
-#include <QSharedDataPointer>
-#include "qt_x11_p.h"
-
-typedef struct _FcPattern FcPattern;
-typedef unsigned long XID;
-typedef XID Colormap;
-typedef XID Window;
-typedef struct _XDisplay Display;
-
-QT_BEGIN_NAMESPACE
-
-class QXcbConnection;
-class QPixmap;
-
-void qt_xcb_native_x11_info_init(QXcbConnection *conn);
-QList<XRectangle> qt_region_to_xrectangles(const QRegion &r);
-
-class QXcbX11InfoData;
-class QXcbX11Info
-{
-public:
- QXcbX11Info();
- ~QXcbX11Info();
- QXcbX11Info(const QXcbX11Info &other);
- QXcbX11Info &operator=(const QXcbX11Info &other);
-
- static QXcbX11Info fromScreen(int screen);
- static Display *display();
-
- int depth() const;
- void setDepth(int depth);
-
- int screen() const;
- Colormap colormap() const;
-
- void *visual() const;
- void setVisual(void *visual);
-
- static int appScreen();
- static int appDepth(int screen = -1);
- static int appCells(int screen = -1);
- static Colormap appColormap(int screen = -1);
- static void *appVisual(int screen = -1);
- static Window appRootWindow(int screen = -1);
- static bool appDefaultColormap(int screen = -1);
- static bool appDefaultVisual(int screen = -1);
- static int appDpiX(int screen = -1);
- static int appDpiY(int screen = -1);
-
-private:
- QSharedDataPointer<QXcbX11InfoData> d;
-
- friend class QX11PaintEngine;
- friend class QX11PlatformPixmap;
- friend void qt_x11SetScreen(QPixmap &pixmap, int screen);
-};
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index 5f712d33d56..e609b84ad5f 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -9,6 +9,7 @@
#include <string.h>
#include <algorithm>
+#include <cstdlib>
static const char *xcb_atomnames = {
// window-manager <-> client protocols
diff --git a/src/plugins/platforms/xcb/qxcbimage.cpp b/src/plugins/platforms/xcb/qxcbimage.cpp
index 5b78c2c08ab..4c978152975 100644
--- a/src/plugins/platforms/xcb/qxcbimage.cpp
+++ b/src/plugins/platforms/xcb/qxcbimage.cpp
@@ -80,12 +80,6 @@ bool qt_xcb_imageFormatForVisual(QXcbConnection *connection, uint8_t depth, cons
*imageFormat = QImage::Format_Grayscale8;
return true;
}
-#if QT_CONFIG(xcb_native_painting)
- if (QXcbIntegration::instance() && QXcbIntegration::instance()->nativePaintingEnabled()) {
- *imageFormat = QImage::Format_Indexed8;
- return true;
- }
-#endif
return false;
}
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index c5c1fb1e638..d3a31dd35c7 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -37,11 +37,6 @@
#include <X11/Xlib.h>
#undef register
#endif
-#if QT_CONFIG(xcb_native_painting)
-#include "qxcbnativepainting.h"
-#include "qpixmap_x11_p.h"
-#include "qbackingstore_x11_p.h"
-#endif
#include <qpa/qplatforminputcontextfactory_p.h>
#include <private/qgenericunixtheme_p.h>
@@ -180,13 +175,6 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
m_services->setConnection(m_connection);
m_fontDatabase.reset(new QGenericUnixFontDatabase());
-
-#if QT_CONFIG(xcb_native_painting)
- if (nativePaintingEnabled()) {
- qCDebug(lcQpaXcb, "QXCB USING NATIVE PAINTING");
- qt_xcb_native_x11_info_init(connection());
- }
-#endif
}
QXcbIntegration::~QXcbIntegration()
@@ -198,11 +186,6 @@ QXcbIntegration::~QXcbIntegration()
QPlatformPixmap *QXcbIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
{
-#if QT_CONFIG(xcb_native_painting)
- if (nativePaintingEnabled())
- return new QX11PlatformPixmap(type);
-#endif
-
return QPlatformIntegration::createPlatformPixmap(type);
}
@@ -281,10 +264,6 @@ QPlatformBackingStore *QXcbIntegration::createPlatformBackingStore(QWindow *wind
const bool isTrayIconWindow = QXcbWindow::isTrayIconWindow(window);
if (isTrayIconWindow) {
backingStore = new QXcbSystemTrayBackingStore(window);
-#if QT_CONFIG(xcb_native_painting)
- } else if (nativePaintingEnabled()) {
- backingStore = new QXcbNativeBackingStore(window);
-#endif
} else {
backingStore = new QXcbBackingStore(window);
}
@@ -576,16 +555,6 @@ void QXcbIntegration::beep() const
xcb_flush(connection);
}
-bool QXcbIntegration::nativePaintingEnabled() const
-{
-#if QT_CONFIG(xcb_native_painting)
- static bool enabled = qEnvironmentVariableIsSet("QT_XCB_NATIVE_PAINTING");
- return enabled;
-#else
- return false;
-#endif
-}
-
#if QT_CONFIG(vulkan)
QPlatformVulkanInstance *QXcbIntegration::createPlatformVulkanInstance(QVulkanInstance *instance) const
{
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 10cc67af55f..041908e4552 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -94,8 +94,6 @@ public:
void beep() const override;
- bool nativePaintingEnabled() const;
-
#if QT_CONFIG(vulkan)
QPlatformVulkanInstance *createPlatformVulkanInstance(QVulkanInstance *instance) const override;
#endif
diff --git a/src/plugins/styles/modernwindows/qwindows11style.cpp b/src/plugins/styles/modernwindows/qwindows11style.cpp
index 33775ecb9bb..2944c02fd79 100644
--- a/src/plugins/styles/modernwindows/qwindows11style.cpp
+++ b/src/plugins/styles/modernwindows/qwindows11style.cpp
@@ -107,6 +107,7 @@ inline ControlState calcControlState(const QStyleOption *option)
#define ChromeRestore u"\uE923"_s
#define ChromeClose u"\uE8BB"_s
+#define More u"\uE712"_s
#define Help u"\uE897"_s
template <typename R, typename P, typename B>
@@ -123,8 +124,8 @@ static constexpr int percentToAlpha(double percent)
}
static constexpr std::array<QColor, 33> WINUI3ColorsLight {
- QColor(0x00,0x00,0x00,0x09), //subtleHighlightColor
- QColor(0x00,0x00,0x00,0x06), //subtlePressedColor
+ QColor(0x00,0x00,0x00,percentToAlpha(3.73)), // subtleHighlightColor (fillSubtleSecondary)
+ QColor(0x00,0x00,0x00,percentToAlpha(2.41)), // subtlePressedColor (fillSubtleTertiary)
QColor(0x00,0x00,0x00,0x0F), //frameColorLight
QColor(0x00,0x00,0x00,percentToAlpha(60.63)), //frameColorStrong
QColor(0x00,0x00,0x00,percentToAlpha(21.69)), //frameColorStrongDisabled
@@ -159,8 +160,8 @@ static constexpr std::array<QColor, 33> WINUI3ColorsLight {
};
static constexpr std::array<QColor, 33> WINUI3ColorsDark {
- QColor(0xFF,0xFF,0xFF,0x0F), //subtleHighlightColor
- QColor(0xFF,0xFF,0xFF,0x0A), //subtlePressedColor
+ QColor(0xFF,0xFF,0xFF,percentToAlpha(6.05)), // subtleHighlightColor (fillSubtleSecondary)
+ QColor(0xFF,0xFF,0xFF,percentToAlpha(4.19)), // subtlePressedColor (fillSubtleTertiary)
QColor(0xFF,0xFF,0xFF,0x12), //frameColorLight
QColor(0xFF,0xFF,0xFF,percentToAlpha(60.47)), //frameColorStrong
QColor(0xFF,0xFF,0xFF,percentToAlpha(15.81)), //frameColorStrongDisabled
@@ -579,21 +580,18 @@ void QWindows11Style::drawComplexControl(ComplexControl control, const QStyleOpt
if (combobox->frame)
drawLineEditFrame(painter, frameRect, combobox, combobox->editable);
- const bool isMouseOver = state & State_MouseOver;
const bool hasFocus = state & State_HasFocus;
- if (isMouseOver && !hasFocus && !highContrastTheme)
- drawRoundedRect(painter, frameRect, Qt::NoPen, winUI3Color(subtleHighlightColor));
+ QStyleOption opt(*option);
+ opt.state.setFlag(QStyle::State_On, false);
+ drawRoundedRect(painter, frameRect, Qt::NoPen, controlFillBrush(&opt, ControlType::Control));
if (sub & SC_ComboBoxArrow) {
QRectF rect = proxy()->subControlRect(CC_ComboBox, option, SC_ComboBoxArrow, widget).adjusted(4, 0, -4, 1);
painter->setFont(d->assetFont);
- painter->setPen(combobox->palette.text().color());
+ painter->setPen(controlTextColor(option));
painter->drawText(rect, Qt::AlignCenter, ChevronDownMed);
}
- if (state & State_HasFocus) {
- drawPrimitive(PE_FrameFocusRect, option, painter, widget);
- }
- if (state & State_KeyboardFocusChange && state & State_HasFocus) {
+ if (state & State_KeyboardFocusChange && hasFocus) {
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*option);
proxy()->drawPrimitive(PE_FrameFocusRect, &fropt, painter, widget);
@@ -870,17 +868,13 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
break;
case PE_IndicatorCheckBox: {
- const bool isRtl = option->direction == Qt::RightToLeft;
const bool isOn = option->state & State_On;
const bool isPartial = option->state & State_NoChange;
- QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0);
+ const QRectF rect = option->rect;
const QPointF center = rect.center();
- rect.setWidth(15);
- rect.setHeight(15);
- rect.moveCenter(center);
- drawRoundedRect(painter, rect, borderPenControlAlt(option),
+ drawRoundedRect(painter, option->rect, borderPenControlAlt(option),
controlFillBrush(option, ControlType::ControlAlt));
if (isOn) {
@@ -924,7 +918,6 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
}
break;
case PE_IndicatorRadioButton: {
- const bool isRtl = option->direction == Qt::RightToLeft;
const bool isOn = option->state & State_On;
qreal innerRadius = radioButtonInnerRadius(state);
if (d->transitionsEnabled() && option->styleObject) {
@@ -935,7 +928,7 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
option->styleObject->setProperty("_q_inner_radius", innerRadius);
}
- QRectF rect = isRtl ? option->rect.adjusted(0, 0, -2, 0) : option->rect.adjusted(2, 0, 0, 0);
+ const QRectF rect = option->rect;
const QPointF center = rect.center();
painter->setPen(borderPenControlAlt(option));
@@ -1052,12 +1045,27 @@ void QWindows11Style::drawPrimitive(PrimitiveElement element, const QStyleOption
if (rect.width() <= 0)
break;
- painter->setPen(Qt::NoPen);
- if (vopt->features & QStyleOptionViewItem::Alternate)
- painter->setBrush(vopt->palette.alternateBase());
- else
- painter->setBrush(vopt->palette.base());
- painter->drawRect(rect);
+ if (vopt->features & QStyleOptionViewItem::Alternate) {
+ QPalette::ColorGroup cg =
+ (widget ? widget->isEnabled() : (vopt->state & QStyle::State_Enabled))
+ ? QPalette::Normal
+ : QPalette::Disabled;
+ if (cg == QPalette::Normal && !(vopt->state & QStyle::State_Active))
+ cg = QPalette::Inactive;
+ painter->fillRect(rect, option->palette.brush(cg, QPalette::AlternateBase));
+ }
+
+ if (option->state & State_Selected && !highContrastTheme) {
+ // keep in sync with CE_ItemViewItem QListView indicator painting
+ const auto col = option->palette.accent().color();
+ painter->setBrush(col);
+ painter->setPen(col);
+ const auto xPos = isRtl ? rect.right() - 4.5f : rect.left() + 3.5f;
+ const auto yOfs = rect.height() / 4.;
+ QRectF r(QPointF(xPos, rect.y() + yOfs),
+ QPointF(xPos + 1, rect.y() + rect.height() - yOfs));
+ painter->drawRoundedRect(r, 1, 1);
+ }
const bool isTreeDecoration = vopt->features.testFlag(
QStyleOptionViewItem::IsDecorationForRootColumn);
@@ -1186,11 +1194,14 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
painter->setRenderHint(QPainter::Antialiasing);
switch (element) {
case QStyle::CE_ComboBoxLabel:
+#if QT_CONFIG(combobox)
if (const QStyleOptionComboBox *cb = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
+ painter->setPen(controlTextColor(option));
QStyleOptionComboBox newOption = *cb;
newOption.rect.adjust(4,0,-4,0);
QCommonStyle::drawControl(element, &newOption, painter, widget);
}
+#endif // QT_CONFIG(combobox)
break;
case QStyle::CE_TabBarTabShape:
#if QT_CONFIG(tabbar)
@@ -1433,26 +1444,6 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
if (!proxy()->styleHint(SH_UnderlineShortcut, btn, widget))
tf |= Qt::TextHideMnemonic;
- if (btn->features & QStyleOptionButton::HasMenu) {
- QPainterStateGuard psg(painter);
-
- const auto indSize = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
- const auto indRect = QRect(btn->rect.right() - indSize - contentItemHMargin, textRect.top(),
- indSize + contentItemHMargin, btn->rect.height());
- const auto vindRect = visualRect(btn->direction, btn->rect, indRect);
- textRect.setWidth(textRect.width() - indSize);
-
- int fontSize = painter->font().pointSize();
- QFont f(d->assetFont);
- f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller
- painter->setFont(f);
- QColor penColor = option->palette.color(isEnabled ? QPalette::Active : QPalette::Disabled,
- QPalette::Text);
- if (isEnabled)
- penColor.setAlpha(percentToAlpha(60.63)); // fillColorTextSecondary
- painter->setPen(penColor);
- painter->drawText(vindRect, Qt::AlignCenter, ChevronDownMed);
- }
if (!btn->icon.isNull()) {
//Center both icon and text
QIcon::Mode mode = isEnabled ? QIcon::Normal : QIcon::Disabled;
@@ -1479,6 +1470,8 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
break;
case CE_PushButtonBevel:
if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ using namespace StyleOptionHelper;
+
QRectF rect = btn->rect.marginsRemoved(QMargins(2, 2, 2, 2));
painter->setPen(Qt::NoPen);
if (btn->features.testFlag(QStyleOptionButton::Flat)) {
@@ -1505,36 +1498,60 @@ void QWindows11Style::drawControl(ControlElement element, const QStyleOption *op
painter->setPen(defaultButton ? WINUI3Colors[colorSchemeIndex][controlStrokeOnAccentSecondary]
: WINUI3Colors[colorSchemeIndex][controlStrokeSecondary]);
}
+ if (btn->features.testFlag(QStyleOptionButton::HasMenu)) {
+ QPainterStateGuard psg(painter);
+
+ const bool isEnabled = !isDisabled(option);
+ QRect textRect = btn->rect.marginsRemoved(QMargins(contentHMargin, 0, contentHMargin, 0));
+ const auto indSize = proxy()->pixelMetric(PM_MenuButtonIndicator, btn, widget);
+ const auto indRect =
+ QRect(btn->rect.right() - indSize - contentItemHMargin, textRect.top(),
+ indSize + contentItemHMargin, btn->rect.height());
+ const auto vindRect = visualRect(btn->direction, btn->rect, indRect);
+ textRect.setWidth(textRect.width() - indSize);
+
+ int fontSize = painter->font().pointSize();
+ QFont f(d->assetFont);
+ f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller
+ painter->setFont(f);
+ QColor penColor = option->palette.color(
+ isEnabled ? QPalette::Active : QPalette::Disabled, QPalette::Text);
+ if (isEnabled)
+ penColor.setAlpha(percentToAlpha(60.63)); // fillColorTextSecondary
+ painter->setPen(penColor);
+ painter->drawText(vindRect, Qt::AlignCenter, ChevronDownMed);
+ }
}
break;
case CE_MenuBarItem:
if (const auto *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) {
+ using namespace StyleOptionHelper;
+
constexpr int hPadding = 11;
constexpr int topPadding = 4;
constexpr int bottomPadding = 6;
- bool active = mbi->state & State_Selected;
- bool hasFocus = mbi->state & State_HasFocus;
- bool down = mbi->state & State_Sunken;
- bool enabled = mbi->state & State_Enabled;
QStyleOptionMenuItem newMbi = *mbi;
+
+ if (auto mbiV2 = qstyleoption_cast<const QStyleOptionMenuItemV2 *>(option))
+ newMbi.state.setFlag(State_Sunken, mbiV2->mouseDown);
+
newMbi.font.setPointSize(10);
- if (enabled && active) {
- if (down)
- painter->setBrushOrigin(painter->brushOriginF() + QPoint(1, 1));
- if (hasFocus) {
- if (highContrastTheme)
- painter->setPen(QPen(newMbi.palette.highlight().color(), 2));
- else
- painter->setPen(Qt::NoPen);
- painter->setBrush(highContrastTheme ? newMbi.palette.window().color() : WINUI3Colors[colorSchemeIndex][subtleHighlightColor]);
- QRect rect = mbi->rect.marginsRemoved(QMargins(5,0,5,0));
- painter->drawRoundedRect(rect,secondLevelRoundingRadius,secondLevelRoundingRadius, Qt::AbsoluteSize);
+ newMbi.palette.setColor(QPalette::ButtonText, controlTextColor(&newMbi));
+ if (!isDisabled(&newMbi)) {
+ QPen pen(Qt::NoPen);
+ QBrush brush(Qt::NoBrush);
+ if (highContrastTheme) {
+ pen = QPen(newMbi.palette.highlight().color(), 2);
+ brush = newMbi.palette.window();
+ } else if (isPressed(&newMbi)) {
+ brush = winUI3Color(subtlePressedColor);
+ } else if (isHover(&newMbi)) {
+ brush = winUI3Color(subtleHighlightColor);
+ }
+ if (pen != Qt::NoPen || brush != Qt::NoBrush) {
+ const QRect rect = mbi->rect.marginsRemoved(QMargins(5, 0, 5, 0));
+ drawRoundedRect(painter, rect, pen, brush);
}
- } else if (enabled && highContrastTheme) {
- painter->setPen(QPen(newMbi.palette.windowText().color(), 2));
- painter->setBrush(newMbi.palette.window().color());
- QRect rect = mbi->rect.marginsRemoved(QMargins(5,0,5,0));
- painter->drawRoundedRect(rect,secondLevelRoundingRadius,secondLevelRoundingRadius, Qt::AbsoluteSize);
}
newMbi.rect.adjust(hPadding,topPadding,-hPadding,-bottomPadding);
painter->setFont(newMbi.font);
@@ -1855,7 +1872,7 @@ QRect QWindows11Style::subElementRect(QStyle::SubElement element, const QStyleOp
case QStyle::SE_RadioButtonIndicator:
case QStyle::SE_CheckBoxIndicator:
ret = QWindowsVistaStyle::subElementRect(element, option, widget);
- ret = ret.marginsRemoved(QMargins(4,0,0,0));
+ ret.moveLeft(contentItemHMargin);
break;
case QStyle::SE_ComboBoxFocusRect:
case QStyle::SE_CheckBoxFocusRect:
@@ -2060,6 +2077,20 @@ QRect QWindows11Style::subControlRect(ComplexControl control, const QStyleOption
}
break;
}
+ case CC_ComboBox: {
+ if (subControl == SC_ComboBoxArrow) {
+ const auto indicatorWidth =
+ proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget);
+ const int endX = option->rect.right() - contentHMargin - 2;
+ const int startX = endX - indicatorWidth;
+ const QRect rect(QPoint(startX, option->rect.top()),
+ QPoint(endX, option->rect.bottom()));
+ ret = visualRect(option->direction, option->rect, rect);
+ } else {
+ ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
+ }
+ break;
+ }
default:
ret = QWindowsVistaStyle::subControlRect(control, option, subControl, widget);
}
@@ -2150,14 +2181,18 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o
break;
}
#endif
+#if QT_CONFIG(combobox)
case CT_ComboBox:
if (const auto *comboBoxOpt = qstyleoption_cast<const QStyleOptionComboBox *>(option)) {
contentSize = QWindowsStyle::sizeFromContents(type, option, size, widget); // don't rely on QWindowsThemeData
contentSize += QSize(4, 4); // default win11 style margins
- if (comboBoxOpt->subControls & SC_ComboBoxArrow)
- contentSize += QSize(8, 0); // arrow margins
+ if (comboBoxOpt->subControls & SC_ComboBoxArrow) {
+ const auto w = proxy()->pixelMetric(PM_MenuButtonIndicator, option, widget);
+ contentSize.rwidth() += w + contentItemHMargin;
+ }
}
break;
+#endif
case CT_HeaderSection:
// windows vista does not honor the indicator (as it was drawn above the text, not on the
// side) so call QWindowsStyle::styleHint directly to get the correct size hint
@@ -2165,6 +2200,27 @@ QSize QWindows11Style::sizeFromContents(ContentsType type, const QStyleOption *o
break;
case CT_RadioButton:
case CT_CheckBox:
+ if (const auto *buttonOpt = qstyleoption_cast<const QStyleOptionButton *>(option)) {
+ const auto p = proxy();
+ const bool isRadio = (type == CT_RadioButton);
+
+ const int width = p->pixelMetric(
+ isRadio ? PM_ExclusiveIndicatorWidth : PM_IndicatorWidth, option, widget);
+ const int height = p->pixelMetric(
+ isRadio ? PM_ExclusiveIndicatorHeight : PM_IndicatorHeight, option, widget);
+
+ int margins = 2 * contentItemHMargin;
+ if (!buttonOpt->icon.isNull() || !buttonOpt->text.isEmpty()) {
+ margins += p->pixelMetric(isRadio ? PM_RadioButtonLabelSpacing
+ : PM_CheckBoxLabelSpacing,
+ option, widget);
+ }
+
+ contentSize += QSize(width + margins, 4);
+ contentSize.setHeight(qMax(size.height(), height + 2 * contentItemHMargin));
+ }
+ break;
+
// the indicator needs 2px more in width when there is no text, not needed when
// the style draws the text
contentSize = QWindowsVistaStyle::sizeFromContents(type, option, size, widget);
@@ -2216,12 +2272,24 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_SliderLength: // same because handle is a circle with r=8
res += 2 * 8;
break;
+ case PM_RadioButtonLabelSpacing:
+ case PM_CheckBoxLabelSpacing:
+ res = 2 * contentItemHMargin;
+ break;
case QStyle::PM_TitleBarButtonIconSize:
res = 16;
break;
case QStyle::PM_TitleBarButtonSize:
res = 32;
break;
+#if QT_CONFIG(toolbar)
+ case PM_ToolBarExtensionExtent:
+ res = int(QStyleHelper::dpiScaled(32., option));
+ break;
+ case PM_ToolBarHandleExtent:
+ res = int(QStyleHelper::dpiScaled(8., option));
+ break;
+#endif // QT_CONFIG(toolbar)
case QStyle::PM_ScrollBarExtent:
res = 12;
break;
@@ -2232,10 +2300,17 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
res = contentItemHMargin;
if (widget) {
const int fontSize = widget->font().pointSize();
- QFont f(d->assetFont);
- f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller
- QFontMetrics fm(f);
- res += fm.horizontalAdvance(ChevronDownMed);
+ auto it = m_fontPoint2ChevronDownMedWidth.find(fontSize);
+ if (it == m_fontPoint2ChevronDownMedWidth.end()) {
+ QFont f(d->assetFont);
+ f.setPointSize(qRound(fontSize * 0.9f)); // a little bit smaller
+ QFontMetrics fm(f);
+ const auto width = fm.horizontalAdvance(ChevronDownMed);
+ m_fontPoint2ChevronDownMedWidth.insert(fontSize, width);
+ res += width;
+ } else {
+ res += it.value();
+ }
} else {
res += 12;
}
@@ -2248,6 +2323,9 @@ int QWindows11Style::pixelMetric(PixelMetric metric, const QStyleOption *option,
case PM_ButtonShiftVertical:
res = 0;
break;
+ case PM_TreeViewIndentation:
+ res = 30;
+ break;
default:
res = QWindowsVistaStyle::pixelMetric(metric, option, widget);
}
@@ -2335,6 +2413,13 @@ void QWindows11Style::unpolish(QWidget *widget)
widget->setProperty("_q_original_menubar_maxheight", QVariant());
}
#endif
+ const auto comboBoxContainer = qobject_cast<const QComboBoxPrivateContainer *>(widget);
+ if (comboBoxContainer) {
+ widget->setAttribute(Qt::WA_OpaquePaintEvent, true);
+ widget->setAttribute(Qt::WA_TranslucentBackground, false);
+ widget->setWindowFlag(Qt::FramelessWindowHint, false);
+ widget->setWindowFlag(Qt::NoDropShadowWindowHint, false);
+ }
if (const auto *scrollarea = qobject_cast<QAbstractScrollArea *>(widget);
scrollarea
@@ -2458,6 +2543,44 @@ void QWindows11Style::polish(QPalette& result)
d->m_titleBarMaxIcon = QIcon();
d->m_titleBarCloseIcon = QIcon();
d->m_titleBarNormalIcon = QIcon();
+ d->m_toolbarExtensionButton = QIcon();
+}
+
+QPixmap QWindows11Style::standardPixmap(StandardPixmap standardPixmap,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ switch (standardPixmap) {
+ case SP_ToolBarHorizontalExtensionButton:
+ case SP_ToolBarVerticalExtensionButton: {
+ const int size = proxy()->pixelMetric(PM_ToolBarExtensionExtent, option, widget);
+ return standardIcon(standardPixmap, option, widget).pixmap(size);
+ }
+ default:
+ break;
+ }
+ return QWindowsVistaStyle::standardPixmap(standardPixmap, option, widget);
+}
+
+QIcon QWindows11Style::standardIcon(StandardPixmap standardIcon,
+ const QStyleOption *option,
+ const QWidget *widget) const
+{
+ auto *d = const_cast<QWindows11StylePrivate*>(d_func());
+ switch (standardIcon) {
+ case SP_ToolBarHorizontalExtensionButton:
+ case SP_ToolBarVerticalExtensionButton: {
+ if (d->m_toolbarExtensionButton.isNull()) {
+ auto e = new WinFontIconEngine(More.at(0), d->assetFont);
+ e->setScale(1.0);
+ d->m_toolbarExtensionButton = QIcon(e);
+ }
+ return d->m_toolbarExtensionButton;
+ }
+ default:
+ break;
+ }
+ return QWindowsVistaStyle::standardIcon(standardIcon, option, widget);
}
QColor QWindows11Style::calculateAccentColor(const QStyleOption *option) const
diff --git a/src/plugins/styles/modernwindows/qwindows11style_p.h b/src/plugins/styles/modernwindows/qwindows11style_p.h
index 130a96430da..736caae956c 100644
--- a/src/plugins/styles/modernwindows/qwindows11style_p.h
+++ b/src/plugins/styles/modernwindows/qwindows11style_p.h
@@ -85,6 +85,10 @@ public:
const QWidget *widget = nullptr) const override;
void polish(QPalette &pal) override;
void unpolish(QWidget *widget) override;
+ QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
+ QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr,
+ const QWidget *widget = nullptr) const override;
protected:
QWindows11Style(QWindows11StylePrivate &dd);
@@ -110,10 +114,15 @@ private:
bool highContrastTheme = false;
int colorSchemeIndex = 0;
+
+ mutable QVarLengthFlatMap<int, int, 8> m_fontPoint2ChevronDownMedWidth;
};
class QWindows11StylePrivate : public QWindowsVistaStylePrivate {
Q_DECLARE_PUBLIC(QWindows11Style)
+
+protected:
+ QIcon m_toolbarExtensionButton;
};
QT_END_NAMESPACE
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
index 85d55f27bb7..22ca18b10bf 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle.cpp
@@ -1626,6 +1626,12 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
break;
case PE_Frame:
+ if (widget && widget->inherits("QComboBoxPrivateContainer")){
+ QStyleOption copy = *option;
+ copy.state |= State_Raised;
+ proxy()->drawPrimitive(PE_PanelMenu, &copy, painter, widget);
+ break;
+ }
#if QT_CONFIG(accessibility)
if (QStyleHelper::isInstanceOf(option->styleObject, QAccessible::EditableText)
|| QStyleHelper::isInstanceOf(option->styleObject, QAccessible::StaticText) ||
@@ -1704,6 +1710,14 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
return;
}
+ case PE_PanelMenu:
+ if (widget && widget->inherits("QComboBoxPrivateContainer")){
+ //fill combobox popup background
+ QWindowsThemeData popupbackgroundTheme(widget, painter, QWindowsVistaStylePrivate::MenuTheme,
+ MENU_POPUPBACKGROUND, stateId, option->rect);
+ d->drawBackground(popupbackgroundTheme);
+ }
+
case PE_PanelMenuBar:
break;
@@ -4968,6 +4982,11 @@ QString WinFontIconEngine::string() const
return m_glyph;
}
+void WinFontIconEngine::setScale(double scale)
+{
+ m_scale = scale;
+}
+
void WinFontIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode mode,
QIcon::State)
{
@@ -4994,7 +5013,7 @@ void WinFontIconEngine::paint(QPainter *painter, const QRect &rect, QIcon::Mode
break;
}
QFont renderFont(m_font);
- renderFont.setPixelSize(rect.height() * 0.7f);
+ renderFont.setPixelSize(rect.height() * m_scale);
painter->save();
painter->setFont(renderFont);
painter->setPen(color);
diff --git a/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h b/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h
index e8aad528f90..cf982ceb133 100644
--- a/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h
+++ b/src/plugins/styles/modernwindows/qwindowsvistastyle_p_p.h
@@ -189,11 +189,13 @@ public:
QString key() const override;
QIconEngine *clone() const override;
QString string() const override;
+ void setScale(double scale);
void paint(QPainter *painter, const QRect &rect, QIcon::Mode mode, QIcon::State state) override;
protected:
QFont m_font;
QChar m_glyph;
+ double m_scale = 0.7;
};
QT_END_NAMESPACE
diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h
index ad3874bd4c9..02ccb9709dc 100644
--- a/src/testlib/qtestcase.h
+++ b/src/testlib/qtestcase.h
@@ -15,6 +15,7 @@
#include <QtCore/qtemporarydir.h>
#include <QtCore/qthread.h>
+#include <chrono>
#ifdef __cpp_concepts
#include <concepts>
#endif
diff --git a/src/tools/bootstrap/CMakeLists.txt b/src/tools/bootstrap/CMakeLists.txt
index ee82d6b99f9..e6f920dcf32 100644
--- a/src/tools/bootstrap/CMakeLists.txt
+++ b/src/tools/bootstrap/CMakeLists.txt
@@ -162,6 +162,7 @@ qt_internal_extend_target(Bootstrap CONDITION CMAKE_CROSSCOMPILING OR NOT QT_FEA
../../3rdparty/pcre2/src/pcre2_chartables.c
../../3rdparty/pcre2/src/pcre2_chkdint.c
../../3rdparty/pcre2/src/pcre2_compile.c
+ ../../3rdparty/pcre2/src/pcre2_compile_cgroup.c
../../3rdparty/pcre2/src/pcre2_compile_class.c
../../3rdparty/pcre2/src/pcre2_config.c
../../3rdparty/pcre2/src/pcre2_context.c
diff --git a/src/tools/windeployqt/main.cpp b/src/tools/windeployqt/main.cpp
index e35330ebeb3..6cb935ef47d 100644
--- a/src/tools/windeployqt/main.cpp
+++ b/src/tools/windeployqt/main.cpp
@@ -592,15 +592,17 @@ static inline int parseArguments(const QStringList &arguments, QCommandLineParse
}
// default to deployment of compiler runtime for windows desktop configurations
- if (options->platform == WindowsDesktopMinGW || options->platform.testFlags(WindowsDesktopMsvc)
- || parser->isSet(compilerRunTimeOption))
+ if (options->platform == WindowsDesktopMinGW || options->platform == WindowsDesktopClangMinGW
+ || options->platform.testFlags(WindowsDesktopMsvc) || parser->isSet(compilerRunTimeOption))
options->compilerRunTime = true;
if (parser->isSet(noCompilerRunTimeOption))
options->compilerRunTime = false;
if (options->compilerRunTime && options->platform != WindowsDesktopMinGW
+ && options->platform != WindowsDesktopClangMinGW
&& !options->platform.testFlags(WindowsDesktopMsvc)) {
- *errorMessage = QStringLiteral("Deployment of the compiler runtime is implemented for Desktop MSVC/g++ only.");
+ *errorMessage = QStringLiteral("Deployment of the compiler runtime is implemented for "
+ "Desktop MSVC and MinGW (g++ and Clang) only.");
return CommandLineParseError;
}
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
index ce30f50616b..c0be3debe49 100644
--- a/src/widgets/CMakeLists.txt
+++ b/src/widgets/CMakeLists.txt
@@ -681,6 +681,7 @@ qt_internal_extend_target(Widgets CONDITION MACOS AND (QT_FEATURE_menu OR QT_FEA
qt_internal_extend_target(Widgets CONDITION QT_FEATURE_colordialog
SOURCES
dialogs/qcolordialog.cpp dialogs/qcolordialog.h
+ dialogs/qcolorwell_p.h
)
qt_internal_extend_target(Widgets CONDITION QT_FEATURE_dialog
diff --git a/src/widgets/accessible/itemviews.cpp b/src/widgets/accessible/itemviews.cpp
index fc969e17380..265c523eae0 100644
--- a/src/widgets/accessible/itemviews.cpp
+++ b/src/widgets/accessible/itemviews.cpp
@@ -60,7 +60,7 @@ int QAccessibleTable::logicalIndex(const QModelIndex &index) const
}
QAccessibleTable::QAccessibleTable(QWidget *w)
- : QAccessibleObject(w)
+ : QAccessibleWidgetV2(w)
{
Q_ASSERT(view());
@@ -677,7 +677,7 @@ void *QAccessibleTable::interface_cast(QAccessible::InterfaceType t)
return static_cast<QAccessibleSelectionInterface*>(this);
if (t == QAccessible::TableInterface)
return static_cast<QAccessibleTableInterface*>(this);
- return nullptr;
+ return QAccessibleWidgetV2::interface_cast(t);
}
void QAccessibleTable::modelChange(QAccessibleTableModelChangeEvent *event)
diff --git a/src/widgets/accessible/itemviews_p.h b/src/widgets/accessible/itemviews_p.h
index 9b30f36ced3..79f9a7f2f05 100644
--- a/src/widgets/accessible/itemviews_p.h
+++ b/src/widgets/accessible/itemviews_p.h
@@ -31,7 +31,9 @@ QT_BEGIN_NAMESPACE
class QAccessibleTableCell;
class QAccessibleTableHeaderCell;
-class QAccessibleTable :public QAccessibleTableInterface, public QAccessibleSelectionInterface, public QAccessibleObject
+class QAccessibleTable : public QAccessibleTableInterface,
+ public QAccessibleSelectionInterface,
+ public QAccessibleWidgetV2
{
public:
explicit QAccessibleTable(QWidget *w);
diff --git a/src/widgets/accessible/qaccessiblewidgets.cpp b/src/widgets/accessible/qaccessiblewidgets.cpp
index 608a99b575d..cd28a61f427 100644
--- a/src/widgets/accessible/qaccessiblewidgets.cpp
+++ b/src/widgets/accessible/qaccessiblewidgets.cpp
@@ -958,54 +958,22 @@ QPoint QAccessibleTextWidget::scrollBarPosition() const
QString QAccessibleTextWidget::textBeforeOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
- Q_ASSERT(startOffset);
- Q_ASSERT(endOffset);
-
- QTextCursor cursor = textCursor();
- cursor.setPosition(offset);
- std::pair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
- cursor.setPosition(boundaries.first - 1);
- boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
-
- *startOffset = boundaries.first;
- *endOffset = boundaries.second;
-
- return text(boundaries.first, boundaries.second);
- }
-
+ return qt_accTextBeforeOffsetHelper(*this, textCursor(), offset, boundaryType, startOffset,
+ endOffset);
+}
QString QAccessibleTextWidget::textAfterOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
- Q_ASSERT(startOffset);
- Q_ASSERT(endOffset);
-
- QTextCursor cursor = textCursor();
- cursor.setPosition(offset);
- std::pair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
- cursor.setPosition(boundaries.second);
- boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
-
- *startOffset = boundaries.first;
- *endOffset = boundaries.second;
-
- return text(boundaries.first, boundaries.second);
+ return qt_accTextAfterOffsetHelper(*this, textCursor(), offset, boundaryType, startOffset,
+ endOffset);
}
QString QAccessibleTextWidget::textAtOffset(int offset, QAccessible::TextBoundaryType boundaryType,
int *startOffset, int *endOffset) const
{
- Q_ASSERT(startOffset);
- Q_ASSERT(endOffset);
-
- QTextCursor cursor = textCursor();
- cursor.setPosition(offset);
- std::pair<int, int> boundaries = QAccessible::qAccessibleTextBoundaryHelper(cursor, boundaryType);
-
- *startOffset = boundaries.first;
- *endOffset = boundaries.second;
-
- return text(boundaries.first, boundaries.second);
+ return qt_accTextAtOffsetHelper(*this, textCursor(), offset, boundaryType, startOffset,
+ endOffset);
}
void QAccessibleTextWidget::setCursorPosition(int position)
diff --git a/src/widgets/accessible/rangecontrols.cpp b/src/widgets/accessible/rangecontrols.cpp
index 741a1589851..1f7b20833dd 100644
--- a/src/widgets/accessible/rangecontrols.cpp
+++ b/src/widgets/accessible/rangecontrols.cpp
@@ -65,6 +65,16 @@ QAccessibleInterface *QAccessibleAbstractSpinBox::lineEditIface() const
#endif
}
+QAccessible::State QAccessibleAbstractSpinBox::state() const
+{
+ QAccessible::State state = QAccessibleWidgetV2::state();
+ if (abstractSpinBox()->isReadOnly())
+ state.readOnly = true;
+ else
+ state.editable = true;
+ return state;
+}
+
QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const
{
if (t == QAccessible::Value)
@@ -338,6 +348,22 @@ void *QAccessibleAbstractSlider::interface_cast(QAccessible::InterfaceType t)
return QAccessibleWidgetV2::interface_cast(t);
}
+QList<QAccessible::Attribute> QAccessibleAbstractSlider::attributeKeys() const
+{
+ QList<QAccessible::Attribute> keys = QAccessibleWidgetV2::attributeKeys();
+ keys.append(QAccessible::Attribute::Orientation);
+
+ return keys;
+}
+
+QVariant QAccessibleAbstractSlider::attributeValue(QAccessible::Attribute key) const
+{
+ if (key == QAccessible::Attribute::Orientation)
+ return QVariant::fromValue(abstractSlider()->orientation());
+
+ return QAccessibleWidgetV2::attributeValue(key);
+}
+
QVariant QAccessibleAbstractSlider::currentValue() const
{
return abstractSlider()->value();
diff --git a/src/widgets/accessible/rangecontrols_p.h b/src/widgets/accessible/rangecontrols_p.h
index 23482556f42..5a023d2f00b 100644
--- a/src/widgets/accessible/rangecontrols_p.h
+++ b/src/widgets/accessible/rangecontrols_p.h
@@ -42,6 +42,7 @@ public:
explicit QAccessibleAbstractSpinBox(QWidget *w);
virtual ~QAccessibleAbstractSpinBox();
+ QAccessible::State state() const override;
QString text(QAccessible::Text t) const override;
void *interface_cast(QAccessible::InterfaceType t) override;
@@ -114,6 +115,10 @@ public:
explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider);
void *interface_cast(QAccessible::InterfaceType t) override;
+ // QAccessibleAttributesInterface
+ QList<QAccessible::Attribute> attributeKeys() const override;
+ QVariant attributeValue(QAccessible::Attribute key) const override;
+
// QAccessibleValueInterface
QVariant currentValue() const override;
void setCurrentValue(const QVariant &value) override;
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index b4ca17b9f64..f8125204045 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -39,6 +39,7 @@
#include "qwindow.h"
#include "private/qdialog_p.h"
+#include "private/qcolorwell_p.h"
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
@@ -56,16 +57,12 @@ namespace QtPrivate {
class QColorLuminancePicker;
class QColorPicker;
class QColorShower;
-class QWellArray;
-class QColorWell;
class QColorPickingEventFilter;
} // namespace QtPrivate
using QColorLuminancePicker = QtPrivate::QColorLuminancePicker;
using QColorPicker = QtPrivate::QColorPicker;
using QColorShower = QtPrivate::QColorShower;
-using QWellArray = QtPrivate::QWellArray;
-using QColorWell = QtPrivate::QColorWell;
using QColorPickingEventFilter = QtPrivate::QColorPickingEventFilter;
class QColorDialogPrivate : public QDialogPrivate
@@ -162,96 +159,6 @@ private:
//////////// QWellArray BEGIN
-namespace QtPrivate {
-
-class QWellArray : public QWidget
-{
- Q_OBJECT
- Q_PROPERTY(int selectedColumn READ selectedColumn)
- Q_PROPERTY(int selectedRow READ selectedRow)
-
-public:
- QWellArray(int rows, int cols, QWidget* parent=nullptr);
- ~QWellArray() {}
- QString cellContent(int row, int col) const;
-
- int selectedColumn() const { return selCol; }
- int selectedRow() const { return selRow; }
-
- virtual void setCurrent(int row, int col);
- virtual void setSelected(int row, int col);
-
- QSize sizeHint() const override;
-
- inline int cellWidth() const
- { return cellw; }
-
- inline int cellHeight() const
- { return cellh; }
-
- inline int rowAt(int y) const
- { return y / cellh; }
-
- inline int columnAt(int x) const
- { if (isRightToLeft()) return ncols - (x / cellw) - 1; return x / cellw; }
-
- inline int rowY(int row) const
- { return cellh * row; }
-
- inline int columnX(int column) const
- { if (isRightToLeft()) return cellw * (ncols - column - 1); return cellw * column; }
-
- inline int numRows() const
- { return nrows; }
-
- inline int numCols() const
- {return ncols; }
-
- inline QRect cellRect() const
- { return QRect(0, 0, cellw, cellh); }
-
- inline QSize gridSize() const
- { return QSize(ncols * cellw, nrows * cellh); }
-
- QRect cellGeometry(int row, int column)
- {
- QRect r;
- if (row >= 0 && row < nrows && column >= 0 && column < ncols)
- r.setRect(columnX(column), rowY(row), cellw, cellh);
- return r;
- }
-
- inline void updateCell(int row, int column) { update(cellGeometry(row, column)); }
-
-signals:
- void selected(int row, int col);
- void currentChanged(int row, int col);
- void colorChanged(int index, QRgb color);
-
-protected:
- virtual void paintCell(QPainter *, int row, int col, const QRect&);
- virtual void paintCellContents(QPainter *, int row, int col, const QRect&);
-
- void mousePressEvent(QMouseEvent*) override;
- void mouseReleaseEvent(QMouseEvent*) override;
- void keyPressEvent(QKeyEvent*) override;
- void focusInEvent(QFocusEvent*) override;
- void focusOutEvent(QFocusEvent*) override;
- void paintEvent(QPaintEvent *) override;
-
-private:
- Q_DISABLE_COPY(QWellArray)
-
- int nrows;
- int ncols;
- int cellw;
- int cellh;
- int curRow;
- int curCol;
- int selRow;
- int selCol;
-};
-
void QWellArray::paintEvent(QPaintEvent *e)
{
QRect r = e->rect();
@@ -476,11 +383,12 @@ void QWellArray::keyPressEvent(QKeyEvent* e)
e->ignore(); // we don't accept the event
return;
}
-
-} // namespace QtPrivate
+}
//////////// QWellArray END
+namespace QtPrivate {
+
// Event filter to be installed on the dialog while in color-picking mode.
class QColorPickingEventFilter : public QObject {
public:
@@ -511,7 +419,7 @@ private:
QColorDialogPrivate *m_dp;
};
-} // unnamed namespace
+} // namespace QtPrivate
/*!
Returns the number of custom colors supported by QColorDialog. All
@@ -571,35 +479,6 @@ static inline void rgb2hsv(QRgb rgb, int &h, int &s, int &v)
c.getHsv(&h, &s, &v);
}
-namespace QtPrivate {
-
-class QColorWell : public QWellArray
-{
-public:
- QColorWell(QWidget *parent, int r, int c, const QRgb *vals)
- :QWellArray(r, c, parent), values(vals), mousePressed(false), oldCurrent(-1, -1)
- { setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); }
-
-protected:
- void paintCellContents(QPainter *, int row, int col, const QRect&) override;
- void mousePressEvent(QMouseEvent *e) override;
- void mouseMoveEvent(QMouseEvent *e) override;
- void mouseReleaseEvent(QMouseEvent *e) override;
-#if QT_CONFIG(draganddrop)
- void dragEnterEvent(QDragEnterEvent *e) override;
- void dragLeaveEvent(QDragLeaveEvent *e) override;
- void dragMoveEvent(QDragMoveEvent *e) override;
- void dropEvent(QDropEvent *e) override;
-#endif
-
-private:
- const QRgb *values;
- bool mousePressed;
- QPoint pressPos;
- QPoint oldCurrent;
-
-};
-
void QColorWell::paintCellContents(QPainter *p, int row, int col, const QRect &r)
{
int i = row + col*numRows();
@@ -687,6 +566,8 @@ void QColorWell::mouseReleaseEvent(QMouseEvent *e)
mousePressed = false;
}
+namespace QtPrivate {
+
class QColorPicker : public QFrame
{
Q_OBJECT
@@ -704,18 +585,21 @@ signals:
protected:
QSize sizeHint() const override;
void paintEvent(QPaintEvent*) override;
+ void keyPressEvent(QKeyEvent *event) override;
void mouseMoveEvent(QMouseEvent *) override;
void mousePressEvent(QMouseEvent *) override;
void resizeEvent(QResizeEvent *) override;
private:
- int hue;
- int sat;
+ QPoint m_pos;
- QPoint colPt();
- int huePt(const QPoint &pt);
- int satPt(const QPoint &pt);
- void setCol(const QPoint &pt);
+ QPixmap createColorsPixmap();
+ QPoint colPt(int hue, int sat);
+ int huePt(const QPoint &pt, const QSize &widgetSize);
+ int huePt(const QPoint &pt) { return huePt(pt, size()); }
+ int satPt(const QPoint &pt, const QSize &widgetSize);
+ int satPt(const QPoint &pt) { return satPt(pt, size()); }
+ void setCol(const QPoint &pt, bool notify = true);
QPixmap pix;
bool crossVisible;
@@ -744,6 +628,7 @@ signals:
protected:
void paintEvent(QPaintEvent*) override;
+ void keyPressEvent(QKeyEvent *event) override;
void mouseMoveEvent(QMouseEvent *) override;
void mousePressEvent(QMouseEvent *) override;
@@ -779,6 +664,7 @@ QColorLuminancePicker::QColorLuminancePicker(QWidget* parent)
hue = 100; val = 100; sat = 100;
pix = nullptr;
// setAttribute(WA_NoErase, true);
+ setFocusPolicy(Qt::StrongFocus);
}
QColorLuminancePicker::~QColorLuminancePicker()
@@ -786,6 +672,21 @@ QColorLuminancePicker::~QColorLuminancePicker()
delete pix;
}
+void QColorLuminancePicker::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Down:
+ setVal(std::clamp(val - 1, 0, 255));
+ break;
+ case Qt::Key_Up:
+ setVal(std::clamp(val + 1, 0, 255));
+ break;
+ default:
+ QWidget::keyPressEvent(event);
+ break;
+ }
+}
+
void QColorLuminancePicker::mouseMoveEvent(QMouseEvent *m)
{
if (m->buttons() == Qt::NoButton) {
@@ -856,38 +757,53 @@ void QColorLuminancePicker::setCol(int h, int s , int v)
repaint();
}
-QPoint QColorPicker::colPt()
+QPoint QColorPicker::colPt(int hue, int sat)
{
QRect r = contentsRect();
return QPoint((360 - hue) * (r.width() - 1) / 360, (255 - sat) * (r.height() - 1) / 255);
}
-int QColorPicker::huePt(const QPoint &pt)
+int QColorPicker::huePt(const QPoint &pt, const QSize &widgetSize)
{
- QRect r = contentsRect();
- return 360 - pt.x() * 360 / (r.width() - 1);
+ QRect r = QRect(QPoint(0, 0), widgetSize) - contentsMargins();
+ return std::clamp(360 - pt.x() * 360 / (r.width() - 1), 0, 359);
}
-int QColorPicker::satPt(const QPoint &pt)
+int QColorPicker::satPt(const QPoint &pt, const QSize &widgetSize)
{
- QRect r = contentsRect();
- return 255 - pt.y() * 255 / (r.height() - 1);
+ QRect r = QRect(QPoint(0, 0), widgetSize) - contentsMargins();
+ return std::clamp(255 - pt.y() * 255 / (r.height() - 1), 0, 255);
}
-void QColorPicker::setCol(const QPoint &pt)
+void QColorPicker::setCol(const QPoint &pt, bool notify)
{
- setCol(huePt(pt), satPt(pt));
+ if (pt == m_pos)
+ return;
+
+ QRect r(m_pos, QSize(20, 20));
+ m_pos.setX(std::clamp(pt.x(), 0, pix.width() - 1));
+ m_pos.setY(std::clamp(pt.y(), 0, pix.height() - 1));
+ r = r.united(QRect(m_pos, QSize(20, 20)));
+ r.translate(contentsRect().x() - 9, contentsRect().y() - 9);
+ // update(r);
+ repaint(r);
+
+ if (notify)
+ emit newCol(huePt(m_pos), satPt(m_pos));
}
QColorPicker::QColorPicker(QWidget* parent)
: QFrame(parent)
, crossVisible(true)
{
- hue = 0; sat = 0;
- setCol(150, 255);
-
setAttribute(Qt::WA_NoSystemBackground);
+ setFocusPolicy(Qt::StrongFocus);
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed) );
+ adjustSize();
+
+ pix = createColorsPixmap();
+
+ setCol(150, 255);
}
QColorPicker::~QColorPicker()
@@ -911,15 +827,31 @@ void QColorPicker::setCol(int h, int s)
{
int nhue = qMin(qMax(0,h), 359);
int nsat = qMin(qMax(0,s), 255);
- if (nhue == hue && nsat == sat)
+ if (nhue == huePt(m_pos) && nsat == satPt(m_pos))
return;
- QRect r(colPt(), QSize(20,20));
- hue = nhue; sat = nsat;
- r = r.united(QRect(colPt(), QSize(20,20)));
- r.translate(contentsRect().x()-9, contentsRect().y()-9);
- // update(r);
- repaint(r);
+ setCol(colPt(nhue, nsat), false);
+}
+
+void QColorPicker::keyPressEvent(QKeyEvent *event)
+{
+ switch (event->key()) {
+ case Qt::Key_Down:
+ setCol(m_pos + QPoint(0, 1));
+ break;
+ case Qt::Key_Left:
+ setCol(m_pos + QPoint(-1, 0));
+ break;
+ case Qt::Key_Right:
+ setCol(m_pos + QPoint(1, 0));
+ break;
+ case Qt::Key_Up:
+ setCol(m_pos + QPoint(0, -1));
+ break;
+ default:
+ QFrame::keyPressEvent(event);
+ break;
+ }
}
void QColorPicker::mouseMoveEvent(QMouseEvent *m)
@@ -930,14 +862,12 @@ void QColorPicker::mouseMoveEvent(QMouseEvent *m)
return;
}
setCol(p);
- emit newCol(hue, sat);
}
void QColorPicker::mousePressEvent(QMouseEvent *m)
{
QPoint p = m->position().toPoint() - contentsRect().topLeft();
setCol(p);
- emit newCol(hue, sat);
}
void QColorPicker::paintEvent(QPaintEvent* )
@@ -949,7 +879,7 @@ void QColorPicker::paintEvent(QPaintEvent* )
p.drawPixmap(r.topLeft(), pix);
if (crossVisible) {
- QPoint pt = colPt() + r.topLeft();
+ QPoint pt = m_pos + r.topLeft();
p.setPen(Qt::black);
p.fillRect(pt.x()-9, pt.y(), 20, 2, Qt::black);
p.fillRect(pt.x(), pt.y()-9, 2, 20, Qt::black);
@@ -960,6 +890,21 @@ void QColorPicker::resizeEvent(QResizeEvent *ev)
{
QFrame::resizeEvent(ev);
+ pix = createColorsPixmap();
+
+ const QSize &oldSize = ev->oldSize();
+ if (!oldSize.isValid())
+ return;
+
+ // calculate hue/saturation based on previous widget size
+ // and update position accordingly
+ const int hue = huePt(m_pos, oldSize);
+ const int sat = satPt(m_pos, oldSize);
+ setCol(hue, sat);
+}
+
+QPixmap QColorPicker::createColorsPixmap()
+{
int w = width() - frameWidth() * 2;
int h = height() - frameWidth() * 2;
QImage img(w, h, QImage::Format_RGB32);
@@ -977,10 +922,9 @@ void QColorPicker::resizeEvent(QResizeEvent *ev)
++x;
}
}
- pix = QPixmap::fromImage(img);
+ return QPixmap::fromImage(img);
}
-
class QColSpinBox : public QSpinBox
{
public:
diff --git a/src/widgets/dialogs/qcolorwell_p.h b/src/widgets/dialogs/qcolorwell_p.h
new file mode 100644
index 00000000000..31d69fabb13
--- /dev/null
+++ b/src/widgets/dialogs/qcolorwell_p.h
@@ -0,0 +1,142 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QCOLORWELL_P_H
+#define QCOLORWELL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtCore/qrect.h>
+#include <QtWidgets/qwidget.h>
+
+QT_REQUIRE_CONFIG(colordialog);
+
+QT_BEGIN_NAMESPACE
+
+class QWellArray : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(int selectedColumn READ selectedColumn)
+ Q_PROPERTY(int selectedRow READ selectedRow)
+
+public:
+ QWellArray(int rows, int cols, QWidget *parent = nullptr);
+ ~QWellArray() { }
+
+ int selectedColumn() const { return selCol; }
+ int selectedRow() const { return selRow; }
+
+ virtual void setCurrent(int row, int col);
+ virtual void setSelected(int row, int col);
+
+ QSize sizeHint() const override;
+
+ inline int cellWidth() const { return cellw; }
+
+ inline int cellHeight() const { return cellh; }
+
+ inline int rowAt(int y) const { return y / cellh; }
+
+ inline int columnAt(int x) const
+ {
+ if (isRightToLeft())
+ return ncols - (x / cellw) - 1;
+ return x / cellw;
+ }
+
+ inline int rowY(int row) const { return cellh * row; }
+
+ inline int columnX(int column) const
+ {
+ if (isRightToLeft())
+ return cellw * (ncols - column - 1);
+ return cellw * column;
+ }
+
+ inline int numRows() const { return nrows; }
+
+ inline int numCols() const { return ncols; }
+
+ inline QRect cellRect() const { return QRect(0, 0, cellw, cellh); }
+
+ inline QSize gridSize() const { return QSize(ncols * cellw, nrows * cellh); }
+
+ QRect cellGeometry(int row, int column)
+ {
+ QRect r;
+ if (row >= 0 && row < nrows && column >= 0 && column < ncols)
+ r.setRect(columnX(column), rowY(row), cellw, cellh);
+ return r;
+ }
+
+ inline void updateCell(int row, int column) { update(cellGeometry(row, column)); }
+
+signals:
+ void selected(int row, int col);
+ void currentChanged(int row, int col);
+ void colorChanged(int index, QRgb color);
+
+protected:
+ virtual void paintCell(QPainter *, int row, int col, const QRect &);
+ virtual void paintCellContents(QPainter *, int row, int col, const QRect &);
+
+ void mousePressEvent(QMouseEvent *) override;
+ void mouseReleaseEvent(QMouseEvent *) override;
+ void keyPressEvent(QKeyEvent *) override;
+ void focusInEvent(QFocusEvent *) override;
+ void focusOutEvent(QFocusEvent *) override;
+ void paintEvent(QPaintEvent *) override;
+
+private:
+ Q_DISABLE_COPY(QWellArray)
+
+ int nrows;
+ int ncols;
+ int cellw;
+ int cellh;
+ int curRow;
+ int curCol;
+ int selRow;
+ int selCol;
+};
+
+class QColorWell : public QWellArray
+{
+public:
+ QColorWell(QWidget *parent, int r, int c, const QRgb *vals)
+ : QWellArray(r, c, parent), values(vals), mousePressed(false), oldCurrent(-1, -1)
+ {
+ setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
+ }
+
+protected:
+ void paintCellContents(QPainter *, int row, int col, const QRect &) override;
+ void mousePressEvent(QMouseEvent *e) override;
+ void mouseMoveEvent(QMouseEvent *e) override;
+ void mouseReleaseEvent(QMouseEvent *e) override;
+#if QT_CONFIG(draganddrop)
+ void dragEnterEvent(QDragEnterEvent *e) override;
+ void dragLeaveEvent(QDragLeaveEvent *e) override;
+ void dragMoveEvent(QDragMoveEvent *e) override;
+ void dropEvent(QDropEvent *e) override;
+#endif
+
+private:
+ const QRgb *values;
+ bool mousePressed;
+ QPoint pressPos;
+ QPoint oldCurrent;
+};
+
+QT_END_NAMESPACE
+
+#endif // QCOLORWELL_P_H
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index d964c9667e6..1ed9dd06e3c 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -3008,7 +3008,6 @@ void QFileDialogPrivate::createWidgets()
qFileDialogUi->lookInCombo->setDuplicatesEnabled(false);
// filename
- qFileDialogUi->fileNameEdit->setFileDialogPrivate(this);
#ifndef QT_NO_SHORTCUT
qFileDialogUi->fileNameLabel->setBuddy(qFileDialogUi->fileNameEdit);
#endif
diff --git a/src/widgets/dialogs/qfiledialog.ui b/src/widgets/dialogs/qfiledialog.ui
index f275e20c633..97f39fa6194 100644
--- a/src/widgets/dialogs/qfiledialog.ui
+++ b/src/widgets/dialogs/qfiledialog.ui
@@ -20,7 +20,10 @@
<item row="0" column="0">
<widget class="QLabel" name="lookInLabel">
<property name="text">
- <string>Look in:</string>
+ <string>&amp;Look in:</string>
+ </property>
+ <property name="buddy">
+ <cstring>lookInCombo</cstring>
</property>
</widget>
</item>
@@ -284,7 +287,10 @@
</sizepolicy>
</property>
<property name="text">
- <string>Files of type:</string>
+ <string>Files of &amp;type:</string>
+ </property>
+ <property name="buddy">
+ <cstring>fileTypeCombo</cstring>
</property>
</widget>
</item>
diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h
index 15044cfd291..dd4a2505def 100644
--- a/src/widgets/dialogs/qfiledialog_p.h
+++ b/src/widgets/dialogs/qfiledialog_p.h
@@ -266,12 +266,9 @@ private:
class QFileDialogLineEdit : public QLineEdit
{
public:
- QFileDialogLineEdit(QWidget *parent = nullptr) : QLineEdit(parent), d_ptr(nullptr){}
- void setFileDialogPrivate(QFileDialogPrivate *d_pointer) {d_ptr = d_pointer; }
+ QFileDialogLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) {}
void keyPressEvent(QKeyEvent *e) override;
bool hideOnEsc;
-private:
- QFileDialogPrivate *d_ptr;
};
class QFileDialogComboBox : public QComboBox
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
index 870b0c40faf..c4f8af1a639 100644
--- a/src/widgets/dialogs/qfontdialog.cpp
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -172,7 +172,7 @@ void QFontDialogPrivate::init()
sizeAccel = new QLabel(q);
#ifndef QT_NO_SHORTCUT
- sizeAccel->setBuddy(sizeEdit);
+ sizeAccel->setBuddy(sizeList);
#endif
sizeAccel->setIndent(2);
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index c4b78539114..bb9f7ab27fc 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -5,15 +5,12 @@
#include "qcommonstyle.h"
#include "qcommonstyle_p.h"
-#include <qfile.h>
#if QT_CONFIG(itemviews)
#include <qabstractitemview.h>
#endif
#include <qapplication.h>
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
-#include <qbitmap.h>
-#include <qcache.h>
#if QT_CONFIG(dockwidget)
#include <qdockwidget.h>
#endif
@@ -61,7 +58,6 @@
#endif
#include <private/qcommonstylepixmaps_p.h>
#include <private/qmath_p.h>
-#include <qdebug.h>
#include <qtextformat.h>
#if QT_CONFIG(wizard)
#include <qwizard.h>
@@ -69,11 +65,6 @@
#if QT_CONFIG(filedialog)
#include <qsidebar_p.h>
#endif
-#include <qfileinfo.h>
-#include <qdir.h>
-#if QT_CONFIG(settings)
-#include <qsettings.h>
-#endif
#include <qvariant.h>
#include <qpixmapcache.h>
#if QT_CONFIG(animation)
@@ -6199,17 +6190,17 @@ QPixmap QCommonStyle::generatedIconPixmap(QIcon::Mode iconMode, const QPixmap &p
return QPixmap::fromImage(std::move(im));
}
case QIcon::Selected: {
- QImage img = pixmap.toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
QColor color = opt->palette.color(QPalette::Normal, QPalette::Highlight);
color.setAlphaF(0.3f);
- QPainter painter(&img);
+ QPixmap ret(pixmap);
+ QPainter painter(&ret);
painter.setCompositionMode(QPainter::CompositionMode_SourceAtop);
- painter.fillRect(0, 0, img.width(), img.height(), color);
+ painter.fillRect(0, 0, pixmap.width(), pixmap.height(), color);
painter.end();
- return QPixmap::fromImage(std::move(img)); }
+ return ret;
+ }
case QIcon::Active:
- return pixmap;
- default:
+ case QIcon::Normal:
break;
}
return pixmap;
diff --git a/src/widgets/styles/qwindowsstyle.cpp b/src/widgets/styles/qwindowsstyle.cpp
index 9b06822c218..b9143a59ee7 100644
--- a/src/widgets/styles/qwindowsstyle.cpp
+++ b/src/widgets/styles/qwindowsstyle.cpp
@@ -851,6 +851,12 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
}
#ifndef QT_NO_FRAME
case PE_Frame:
+ if (w && w->inherits("QComboBoxPrivateContainer")){
+ QStyleOption copy = *opt;
+ copy.state |= State_Raised;
+ proxy()->drawPrimitive(PE_PanelMenu, &copy, p, w);
+ break;
+ }
case PE_FrameMenu:
if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
if (frame->lineWidth == 2 || pe == PE_Frame) {
@@ -873,6 +879,7 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
}
} else {
QPalette popupPal = opt->palette;
+ p->drawRect(opt->rect);
popupPal.setColor(QPalette::Light, opt->palette.window().color());
popupPal.setColor(QPalette::Midlight, opt->palette.light().color());
qDrawWinPanel(p, opt->rect, popupPal, opt->state & State_Sunken);
@@ -899,6 +906,12 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt,
p->drawRect(opt->rect);
}
break; }
+ case PE_PanelMenu:
+ if (w && w->inherits("QComboBoxPrivateContainer")){
+ const QBrush menuBackground = opt->palette.base().color();
+ QColor borderColor = opt->palette.window().color();
+ qDrawPlainRect(p, opt->rect, borderColor, 1, &menuBackground);
+ }
case PE_FrameWindow: {
QPalette popupPal = opt->palette;
popupPal.setColor(QPalette::Light, opt->palette.window().color());
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp
index 55e6137dba9..ee80cca649c 100644
--- a/src/widgets/widgets/qlineedit_p.cpp
+++ b/src/widgets/widgets/qlineedit_p.cpp
@@ -353,17 +353,16 @@ QLineEditPrivate *QLineEditIconButton::lineEditPrivate() const
void QLineEditIconButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
- QIcon::Mode state = QIcon::Disabled;
+ QIcon::Mode mode = QIcon::Disabled;
if (isEnabled())
- state = isDown() ? QIcon::Active : QIcon::Normal;
+ mode = isDown() ? QIcon::Active : QIcon::Normal;
const QLineEditPrivate *lep = lineEditPrivate();
const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16;
const QSize iconSize(iconWidth, iconWidth);
- const QPixmap iconPixmap = icon().pixmap(iconSize, devicePixelRatio(), state, QIcon::Off);
QRect pixmapRect = QRect(QPoint(0, 0), iconSize);
pixmapRect.moveCenter(rect().center());
painter.setOpacity(m_opacity);
- painter.drawPixmap(pixmapRect, iconPixmap);
+ icon().paint(&painter, pixmapRect, Qt::AlignCenter, mode, QIcon::Off);
}
void QLineEditIconButton::actionEvent(QActionEvent *e)
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 0b562a47879..8e6f497d7f5 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -1003,7 +1003,7 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text)
++tab->lastTab;
}
- if (tabAt(d->mousePosition) == index) {
+ if (isVisible() && tabAt(d->mousePosition) == index) {
d->hoverIndex = index;
d->hoverRect = tabRect(index);
}
diff --git a/tests/auto/cmake/RunCMake/Sbom/CMakeLists.txt b/tests/auto/cmake/RunCMake/Sbom/CMakeLists.txt
index d0ef37d817f..e9578d7246a 100644
--- a/tests/auto/cmake/RunCMake/Sbom/CMakeLists.txt
+++ b/tests/auto/cmake/RunCMake/Sbom/CMakeLists.txt
@@ -1,3 +1,7 @@
cmake_minimum_required(VERSION 3.16)
project(${RunCMake_TEST} LANGUAGES CXX)
-include(${RunCMake_TEST}.cmake)
+
+# To allow including the gen files in other subdirectory projects.
+list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+include(${SBOM_INCLUDE_FILE}.cmake)
diff --git a/tests/auto/cmake/RunCMake/Sbom/RunCMakeTest.cmake b/tests/auto/cmake/RunCMake/Sbom/RunCMakeTest.cmake
index 3103e651093..81e83ccead3 100644
--- a/tests/auto/cmake/RunCMake/Sbom/RunCMakeTest.cmake
+++ b/tests/auto/cmake/RunCMake/Sbom/RunCMakeTest.cmake
@@ -1,27 +1,68 @@
include(QtRunCMake)
-function(run_cmake_and_build case)
+function(run_cmake_and_build case format_case)
+ set(include_file "${case}")
+ set(case "${format_case}-${case}")
+
# Set common build directory for configure and build
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
set(options
"-DQt6_DIR=${Qt6_DIR}"
"-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/installed"
+ "-DSBOM_INCLUDE_FILE=${include_file}"
+ "-DFORMAT_CASE=${format_case}"
)
+ if(format_case STREQUAL "spdx23")
+ list(APPEND options
+ -DQT_GENERATE_SBOM=ON
+ -DQT_SBOM_GENERATE_SPDX_V2=ON
+ -DQT_SBOM_GENERATE_CYDX_V1_6=OFF
+ )
+ elseif(format_case STREQUAL "cydx16")
+ list(APPEND options
+ -DQT_GENERATE_SBOM=ON
+ -DQT_SBOM_GENERATE_SPDX_V2=OFF
+ -DQT_SBOM_GENERATE_CYDX_V1_6=ON
+ )
+ elseif(format_case STREQUAL "all")
+ list(APPEND options
+ -DQT_GENERATE_SBOM=ON
+ -DQT_SBOM_GENERATE_SPDX_V2=ON
+ -DQT_SBOM_GENERATE_CYDX_V1_6=ON
+ )
+ elseif(format_case STREQUAL "none")
+ list(APPEND options
+ -DQT_GENERATE_SBOM=OFF
+ )
+ endif()
+
+ # Check CI environment variables for SBOM options to ensure we only enabled checks that
+ # require additional dependencies on machines that actually have them.
+ # Also allow force enabling all checks via QT_SBOM_FORCE_ALL_CHECKS env var.
set(maybe_sbom_env_args "$ENV{SBOM_COMMON_ARGS}")
+ set(force_all_checks "$ENV{QT_SBOM_FORCE_ALL_CHECKS}")
- if(maybe_sbom_env_args MATCHES "QT_INTERNAL_SBOM_DEFAULT_CHECKS=ON")
+ if(maybe_sbom_env_args MATCHES "QT_INTERNAL_SBOM_DEFAULT_CHECKS=ON"
+ OR force_all_checks)
list(APPEND options "-DQT_INTERNAL_SBOM_DEFAULT_CHECKS=ON")
endif()
- if(maybe_sbom_env_args MATCHES "QT_INTERNAL_SBOM_AUDIT=ON")
+ if(maybe_sbom_env_args MATCHES "QT_INTERNAL_SBOM_AUDIT=ON"
+ OR force_all_checks)
list(APPEND options "-DQT_INTERNAL_SBOM_AUDIT=ON")
endif()
- if(maybe_sbom_env_args MATCHES "QT_INTERNAL_SBOM_AUDIT_NO_ERROR=ON")
+ if(maybe_sbom_env_args MATCHES "QT_INTERNAL_SBOM_AUDIT_NO_ERROR=ON"
+ OR force_all_checks)
list(APPEND options "-DQT_INTERNAL_SBOM_AUDIT_NO_ERROR=ON")
endif()
+ if(maybe_sbom_env_args MATCHES "QT_SBOM_REQUIRE_GENERATE_CYDX_V1_6=ON"
+ OR force_all_checks)
+ list(APPEND options "-DQT_SBOM_REQUIRE_GENERATE_CYDX_V1_6=ON")
+ endif()
+
# Need to pass the python interpreter paths, to avoid sbom2doc not found errors.
# This mirrors what coin/instructions/prepare_building_env.yaml does.
set(maybe_python3_path "$ENV{PYTHON3_PATH}")
@@ -42,9 +83,17 @@ function(run_cmake_and_build case)
# fine.
set(RunCMake_TEST_OUTPUT_MERGE 1)
run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
+
+ # Check the sbom files are present after installation.
+ set(RunCMake-check-file "check.cmake")
run_cmake_command(${case}-install ${CMAKE_COMMAND} --install .)
+ unset(RunCMake-check-file)
endfunction()
-run_cmake_and_build(minimal)
-run_cmake_and_build(full)
-run_cmake_and_build(versions)
+set(format_cases spdx23 cydx16 all none)
+foreach(format_case IN LISTS format_cases)
+ run_cmake_and_build(minimal "${format_case}")
+ run_cmake_and_build(full "${format_case}")
+ run_cmake_and_build(versions "${format_case}")
+endforeach()
+
diff --git a/tests/auto/cmake/RunCMake/Sbom/check.cmake b/tests/auto/cmake/RunCMake/Sbom/check.cmake
new file mode 100644
index 00000000000..9e143e35ab2
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/check.cmake
@@ -0,0 +1,63 @@
+function(check_exists file)
+ if(NOT EXISTS "${file}")
+ get_filename_component(file_dir "${file}" DIRECTORY)
+ file(GLOB dir_contents "${file_dir}/*")
+ string(APPEND RunCMake_TEST_FAILED "${file} does not exist\n. "
+ "Contents of directory ${file_dir}:\n ${dir_contents}\n")
+ endif()
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+function(check_not_exists file)
+ if(EXISTS "${file}")
+ get_filename_component(file_dir "${file}" DIRECTORY)
+ file(GLOB dir_contents "${file_dir}/*")
+ string(APPEND RunCMake_TEST_FAILED "${file} exists\n. "
+ "Contents of directory ${file_dir}:\n ${dir_contents}\n")
+ endif()
+ set(RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}" PARENT_SCOPE)
+endfunction()
+
+# Check that the correct option values are used for the project root sbom.
+set(root_result_file "${RunCMake_TEST_BINARY_DIR}/result.cmake")
+if(EXISTS "${root_result_file}")
+ include("${root_result_file}")
+
+ if(NOT "${ORIGINAL_QT_GENERATE_SBOM}" STREQUAL "${RESULT_QT_GENERATE_SBOM}")
+ string(APPEND RunCMake_TEST_FAILED
+ "QT_GENERATE_SBOM is ${RESULT_QT_GENERATE_SBOM}, expected ${ORIGINAL_QT_GENERATE_SBOM} \n")
+ endif()
+
+ if(NOT "${ORIGINAL_QT_SBOM_GENERATE_SPDX_V2}" STREQUAL "${RESULT_QT_SBOM_GENERATE_SPDX_V2}")
+ string(APPEND RunCMake_TEST_FAILED
+ "QT_SBOM_GENERATE_SPDX_V2 is ${RESULT_QT_SBOM_GENERATE_SPDX_V2}, "
+ "expected ${ORIGINAL_QT_SBOM_GENERATE_SPDX_V2} \n")
+ endif()
+
+ if(NOT "${ORIGINAL_QT_SBOM_GENERATE_CYDX_V1_6}" STREQUAL "${RESULT_QT_SBOM_GENERATE_CYDX_V1_6}")
+ string(APPEND RunCMake_TEST_FAILED
+ "QT_SBOM_GENERATE_CYDX_V1_6 is ${RESULT_QT_SBOM_GENERATE_CYDX_V1_6}, "
+ "expected ${ORIGINAL_QT_SBOM_GENERATE_CYDX_V1_6} \n")
+ endif()
+endif()
+
+
+# Glob for all result.cmake files recursively in the root of the test binary dir, and run checks
+# for each of them.
+file(GLOB_RECURSE result_files
+ "${RunCMake_TEST_BINARY_DIR}/**/result.cmake"
+)
+
+# Confirm that the all subproject sbom files are installed, including the root one.
+foreach(result_file IN LISTS result_files)
+ include("${result_file}")
+
+ foreach(sbom_doc IN LISTS SBOM_DOCUMENTS)
+ check_exists("${sbom_doc}")
+ endforeach()
+
+ foreach(sbom_doc IN LISTS NO_SBOM_DOCUMENTS)
+ check_not_exists("${sbom_doc}")
+ endforeach()
+endforeach()
+
diff --git a/tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGen.cmake b/tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGen.cmake
new file mode 100644
index 00000000000..a892fee2082
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGen.cmake
@@ -0,0 +1,67 @@
+if(NOT SBOM_PROJECT_NAME)
+ set(SBOM_PROJECT_NAME "${PROJECT_NAME}")
+endif()
+# Convert to lower case, otherwise on case-sensitive filesystems the generated
+# filenames may not match the expected ones.
+string(TOLOWER "${SBOM_PROJECT_NAME}" SBOM_PROJECT_NAME)
+
+if(NOT SBOM_VERSION)
+ set(SBOM_VERSION "1.0.0")
+endif()
+
+if(NOT SBOM_INSTALL_DIR)
+ set(SBOM_INSTALL_DIR "sbom")
+endif()
+
+set(sbom_document_base_name "${SBOM_PROJECT_NAME}-${SBOM_VERSION}")
+set(sbom_install_dir "${CMAKE_BINARY_DIR}/installed/${SBOM_INSTALL_DIR}")
+
+set(spdx_file "${sbom_install_dir}/${sbom_document_base_name}.spdx")
+set(spdx_json_file "${sbom_install_dir}/${sbom_document_base_name}.spdx.json")
+set(cydx_file "${sbom_install_dir}/${sbom_document_base_name}.cdx.json")
+
+set(sbom_documents "")
+set(no_sbom_documents "")
+
+if(FORMAT_CASE STREQUAL "spdx23" OR FORMAT_CASE STREQUAL "all")
+ if(QT_SBOM_GENERATE_SPDX_V2)
+ list(APPEND sbom_documents "${spdx_file}")
+ else()
+ list(APPEND no_sbom_documents "${spdx_file}")
+ endif()
+
+ if(QT_SBOM_GENERATE_SPDX_V2_JSON)
+ list(APPEND sbom_documents "${spdx_json_file}")
+ else()
+ list(APPEND no_sbom_documents "${spdx_json_file}")
+ endif()
+endif()
+
+if(FORMAT_CASE STREQUAL "cydx16" OR FORMAT_CASE STREQUAL "all")
+ if(QT_SBOM_GENERATE_CYDX_V1_6)
+ list(APPEND sbom_documents "${cydx_file}")
+ else()
+ list(APPEND no_sbom_documents "${cydx_file}")
+ endif()
+endif()
+
+if(FORMAT_CASE STREQUAL "none")
+ set(no_sbom_documents ${spdx_file} ${spdx_json_file} ${cydx_file})
+ set(sbom_documents "")
+endif()
+
+# These values will be used by the check.cmake script after installation.
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/result.cmake"
+ CONTENT
+ "
+set(SBOM_DOCUMENTS \"${sbom_documents}\")
+set(NO_SBOM_DOCUMENTS \"${no_sbom_documents}\")
+set(ORIGINAL_QT_GENERATE_SBOM \"${original_QT_GENERATE_SBOM}\")
+set(ORIGINAL_QT_SBOM_GENERATE_SPDX_V2 \"${original_QT_SBOM_GENERATE_SPDX_V2}\")
+set(ORIGINAL_QT_SBOM_GENERATE_CYDX_V1_6 \"${original_QT_SBOM_GENERATE_CYDX_V1_6}\")
+set(RESULT_QT_GENERATE_SBOM \"${QT_GENERATE_SBOM}\")
+set(RESULT_QT_SBOM_GENERATE_SPDX_V2 \"${QT_SBOM_GENERATE_SPDX_V2}\")
+set(RESULT_QT_SBOM_GENERATE_CYDX_V1_6 \"${QT_SBOM_GENERATE_CYDX_V1_6}\")
+"
+)
diff --git a/tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGenIntro.cmake b/tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGenIntro.cmake
new file mode 100644
index 00000000000..11ec50d76d6
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/cmake/CommonResultGenIntro.cmake
@@ -0,0 +1,12 @@
+# Record the sbom option values before they might be modified by an sbom_setup call, due to
+# missing python dependencies.
+set(original_QT_GENERATE_SBOM "${QT_GENERATE_SBOM}")
+set(original_QT_SBOM_GENERATE_SPDX_V2 "${QT_SBOM_GENERATE_SPDX_V2}")
+set(original_QT_SBOM_GENERATE_CYDX_V1_6 "${QT_SBOM_GENERATE_CYDX_V1_6}")
+
+# Explicitly set these because none case only has QT_GENERATE_SBOM passed as OFF.
+# In this case, the defaults for the formats is to remain ON.
+if(NOT QT_GENERATE_SBOM)
+ set(original_QT_SBOM_GENERATE_SPDX_V2 ON)
+ set(original_QT_SBOM_GENERATE_CYDX_V1_6 ON)
+endif()
diff --git a/tests/auto/cmake/RunCMake/Sbom/full.cmake b/tests/auto/cmake/RunCMake/Sbom/full.cmake
index 7241b8e77a8..b5ac77c3ccc 100644
--- a/tests/auto/cmake/RunCMake/Sbom/full.cmake
+++ b/tests/auto/cmake/RunCMake/Sbom/full.cmake
@@ -1,23 +1,30 @@
# Needed to make the sbom functions available.
find_package(Qt6 REQUIRED Core)
+include(CommonResultGenIntro)
+
_qt_internal_setup_sbom(
GENERATE_SBOM_DEFAULT "TRUE"
)
set(IS_FULL_BUILD "TRUE")
+# These are used by common_result_gen.cmake.
+set(SBOM_VERSION "2.0.0")
+set(SBOM_INSTALL_DIR "sbom_full")
+set(SBOM_PROJECT_NAME "${PROJECT_NAME}ProjectFull")
+
_qt_internal_sbom_begin_project(
- SBOM_PROJECT_NAME "${PROJECT_NAME}Project"
+ SBOM_PROJECT_NAME "${SBOM_PROJECT_NAME}"
SUPPLIER "QtProjectTest"
SUPPLIER_URL "https://qt-project.org/SbomTest"
LICENSE_EXPRESSION "LGPL-3.0-only"
COPYRIGHTS "2025 The Qt Company Ltd."
INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}"
- INSTALL_SBOM_DIR "sbom"
+ INSTALL_SBOM_DIR "${SBOM_INSTALL_DIR}"
DOWNLOAD_LOCATION "https://download.qt.io/sbom"
CPE "cpe:2.3:a:qt:qtprojecttest:1.0.0:*:*:*:*:*:*:*"
- VERSION "1.0.0"
+ VERSION "${SBOM_VERSION}"
DOCUMENT_CREATOR_TOOL "Test Build System Tool"
LICENSE_DIR_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/custom_licenses"
)
@@ -26,3 +33,7 @@ include(common_targets.cmake)
_qt_internal_sbom_end_project()
+include(CommonResultGen)
+
+# Also create separate sboms for some sibling projects under this subdir.
+add_subdirectory(subprojects)
diff --git a/tests/auto/cmake/RunCMake/Sbom/minimal.cmake b/tests/auto/cmake/RunCMake/Sbom/minimal.cmake
index 4422314b2d5..27dfc0a3b12 100644
--- a/tests/auto/cmake/RunCMake/Sbom/minimal.cmake
+++ b/tests/auto/cmake/RunCMake/Sbom/minimal.cmake
@@ -1,17 +1,26 @@
# Needed to make the sbom functions available.
find_package(Qt6 REQUIRED Core)
+include(CommonResultGenIntro)
+
_qt_internal_setup_sbom(
GENERATE_SBOM_DEFAULT "TRUE"
)
+# This is used by common_result_gen.cmake.
+set(SBOM_VERSION "1.0.0")
+
_qt_internal_sbom_begin_project(
SUPPLIER "QtProjectTest"
SUPPLIER_URL "https://qt-project.org/SbomTest"
- VERSION "1.0.0"
+ VERSION "${SBOM_VERSION}"
)
include(common_targets.cmake)
_qt_internal_sbom_end_project()
+include(CommonResultGen)
+
+# Also create separate sboms for some sibling projects under this subdir.
+add_subdirectory(subprojects)
diff --git a/tests/auto/cmake/RunCMake/Sbom/subprojects/CMakeLists.txt b/tests/auto/cmake/RunCMake/Sbom/subprojects/CMakeLists.txt
new file mode 100644
index 00000000000..0d9e12534df
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/subprojects/CMakeLists.txt
@@ -0,0 +1,5 @@
+# These subprojects look up the same system library dependency separately in each subdirectory
+# scope to ensure that we simulate the same scenario as in a top-level qt5.git build, so that
+# we try to reuse the same system library entity in multiple sboms.
+add_subdirectory(subproj1)
+add_subdirectory(subproj2)
diff --git a/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/CMakeLists.txt b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/CMakeLists.txt
new file mode 100644
index 00000000000..a59908d8889
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/CMakeLists.txt
@@ -0,0 +1,51 @@
+project(subproj1)
+
+# This is used by common_result_gen.cmake.
+set(SBOM_VERSION "1.0.1")
+set(SBOM_PROJECT_NAME "${PROJECT_NAME}")
+
+_qt_internal_sbom_begin_project(
+ SBOM_PROJECT_NAME "${SBOM_PROJECT_NAME}"
+ INSTALL_SBOM_DIR "${SBOM_INSTALL_DIR}"
+ SUPPLIER "QtProjectTest"
+ SUPPLIER_URL "https://qt-project.org/SbomTest"
+ VERSION "${SBOM_VERSION}"
+)
+
+add_library(subproj1_helper STATIC)
+target_sources(subproj1_helper PRIVATE subproj1_helper.cpp)
+target_link_libraries(subproj1_helper)
+install(TARGETS subproj1_helper
+ RUNTIME DESTINATION bin
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+)
+_qt_internal_add_sbom(subproj1_helper
+ TYPE "LIBRARY"
+ RUNTIME_PATH bin
+ ARCHIVE_PATH lib
+ LIBRARY_PATH lib
+)
+
+
+# This will actually refer to the root project Threads, that gets brought in via Qt6::Core
+# dependency.
+find_package(Threads)
+if(TARGET Threads::Threads)
+ _qt_internal_add_sbom(Threads::Threads
+ TYPE SYSTEM_LIBRARY
+ )
+ target_link_libraries(subproj1_helper PRIVATE Threads::Threads)
+endif()
+
+# Create another IMPORTED target that is meant to simulate a system library, so we don't refer to
+# a target that exists in the root scope.
+add_library(FancySystemLib IMPORTED INTERFACE)
+_qt_internal_add_sbom(FancySystemLib
+ TYPE SYSTEM_LIBRARY
+)
+target_link_libraries(subproj1_helper PRIVATE FancySystemLib)
+
+_qt_internal_sbom_end_project()
+
+include(CommonResultGen)
diff --git a/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/subproj1_helper.cpp b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/subproj1_helper.cpp
new file mode 100644
index 00000000000..f6b17d4b9f8
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj1/subproj1_helper.cpp
@@ -0,0 +1,4 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+int func() { return 0; };
diff --git a/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/CMakeLists.txt b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/CMakeLists.txt
new file mode 100644
index 00000000000..0a408ddf47f
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/CMakeLists.txt
@@ -0,0 +1,46 @@
+project(subproj2)
+
+# This is used by common_result_gen.cmake.
+set(SBOM_VERSION "1.0.2")
+set(SBOM_PROJECT_NAME "${PROJECT_NAME}")
+
+_qt_internal_sbom_begin_project(
+ SBOM_PROJECT_NAME "${SBOM_PROJECT_NAME}"
+ INSTALL_SBOM_DIR "${SBOM_INSTALL_DIR}"
+ SUPPLIER "QtProjectTest"
+ SUPPLIER_URL "https://qt-project.org/SbomTest"
+ VERSION "${SBOM_VERSION}"
+)
+
+add_library(subproj2_helper STATIC)
+target_sources(subproj2_helper PRIVATE subproj2_helper.cpp)
+target_link_libraries(subproj2_helper)
+install(TARGETS subproj2_helper
+ RUNTIME DESTINATION bin
+ ARCHIVE DESTINATION lib
+ LIBRARY DESTINATION lib
+)
+_qt_internal_add_sbom(subproj2_helper
+ TYPE "LIBRARY"
+ RUNTIME_PATH bin
+ ARCHIVE_PATH lib
+ LIBRARY_PATH lib
+)
+
+find_package(Threads)
+if(TARGET Threads::Threads)
+ _qt_internal_add_sbom(Threads::Threads
+ TYPE SYSTEM_LIBRARY
+ )
+ target_link_libraries(subproj2_helper PRIVATE Threads::Threads)
+endif()
+
+add_library(FancySystemLib IMPORTED INTERFACE)
+_qt_internal_add_sbom(FancySystemLib
+ TYPE SYSTEM_LIBRARY
+)
+target_link_libraries(subproj2_helper PRIVATE FancySystemLib)
+
+_qt_internal_sbom_end_project()
+
+include(CommonResultGen)
diff --git a/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/subproj2_helper.cpp b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/subproj2_helper.cpp
new file mode 100644
index 00000000000..f6b17d4b9f8
--- /dev/null
+++ b/tests/auto/cmake/RunCMake/Sbom/subprojects/subproj2/subproj2_helper.cpp
@@ -0,0 +1,4 @@
+// Copyright (C) 2025 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+int func() { return 0; };
diff --git a/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp b/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
index d8da8ecc03b..c2c09a234c8 100644
--- a/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
+++ b/tests/auto/corelib/animation/qparallelanimationgroup/tst_qparallelanimationgroup.cpp
@@ -74,13 +74,13 @@ class TestAnimation : public QVariantAnimation
{
Q_OBJECT
public:
- virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)};
+ virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)}
virtual void updateState(QAbstractAnimation::State newState,
QAbstractAnimation::State oldState) override
{
Q_UNUSED(oldState);
Q_UNUSED(newState);
- };
+ }
};
class TestAnimation2 : public QVariantAnimation
@@ -90,13 +90,13 @@ public:
TestAnimation2(QAbstractAnimation *animation) : QVariantAnimation(animation) {}
TestAnimation2(int duration, QAbstractAnimation *animation) : QVariantAnimation(animation), m_duration(duration) {}
- virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)};
+ virtual void updateCurrentValue(const QVariant &value) override { Q_UNUSED(value)}
virtual void updateState(QAbstractAnimation::State newState,
QAbstractAnimation::State oldState) override
{
Q_UNUSED(oldState);
Q_UNUSED(newState);
- };
+ }
virtual int duration() const override {
return m_duration;
@@ -463,8 +463,9 @@ void tst_QParallelAnimationGroup::deleteChildrenWithRunningGroup()
QCOMPARE(group.state(), QAnimationGroup::Running);
QCOMPARE(anim1->state(), QAnimationGroup::Running);
- QTest::qWait(80);
- QVERIFY(group.currentLoopTime() > 0);
+ QTest::qWaitFor([&]{
+ return group.currentLoopTime() > 0;
+ }, 200ms);
delete anim1;
QCOMPARE(group.animationCount(), 0);
diff --git a/tests/auto/corelib/global/qcheckedint/tst_qcheckedint.cpp b/tests/auto/corelib/global/qcheckedint/tst_qcheckedint.cpp
index fe509e558c6..72175f8e04c 100644
--- a/tests/auto/corelib/global/qcheckedint/tst_qcheckedint.cpp
+++ b/tests/auto/corelib/global/qcheckedint/tst_qcheckedint.cpp
@@ -347,7 +347,7 @@ void tst_QCheckedInt::division()
// This causes an internal compiler error on MSVC, so skipping it there
// Integrity's compiler says this code isn't constexpr.
-#if (!defined(Q_CC_MSVC) || Q_CC_MSVC > 1944) && !defined(Q_CC_GHS)
+#if (!defined(Q_CC_MSVC) || Q_CC_MSVC > 1950) && !defined(Q_CC_GHS)
template <typename T>
constexpr bool checkedIntTypeProperties()
diff --git a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
index bbe355061eb..0474ad974cb 100644
--- a/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
+++ b/tests/auto/corelib/global/qgetputenv/tst_qgetputenv.cpp
@@ -17,15 +17,26 @@ class tst_QGetPutEnv : public QObject
{
Q_OBJECT
private slots:
+ void init();
+
void getSetCheck();
void encoding();
void intValue_data();
void intValue();
+
+private:
+ QByteArray uniqueEnvVarName;
};
+void tst_QGetPutEnv::init()
+{
+ QUuid uuid = QUuid::createUuid();
+ uniqueEnvVarName = "QT_TEST_ENV_VAR_" + uuid.toByteArray(QUuid::Id128);
+}
+
void tst_QGetPutEnv::getSetCheck()
{
- const char varName[] = "should_not_exist";
+ const char *varName = uniqueEnvVarName.constData();
bool ok;
@@ -117,13 +128,14 @@ void tst_QGetPutEnv::encoding()
// The LATIN SMALL LETTER A WITH ACUTE is NFC for NFD:
// U+0061 U+0301 LATIN SMALL LETTER A + COMBINING ACUTE ACCENT
- const char varName[] = "should_not_exist";
+ const char *varName = uniqueEnvVarName.constData();
+
static const wchar_t rawvalue[] = { 'a', 0x00E1, 0x03B1, 0x0430, 0 };
QString value = QString::fromWCharArray(rawvalue);
#if defined(Q_OS_WIN)
- const wchar_t wvarName[] = L"should_not_exist";
- _wputenv_s(wvarName, rawvalue);
+ std::wstring wvarName = QString::fromUtf8(varName).toStdWString();
+ _wputenv_s(wvarName.data(), rawvalue);
#else
// confirm the locale is UTF-8
if (value.toLocal8Bit() != "a\xc3\xa1\xce\xb1\xd0\xb0")
@@ -203,7 +215,7 @@ void tst_QGetPutEnv::intValue_data()
void tst_QGetPutEnv::intValue()
{
const int maxlen = (sizeof(qint64) * CHAR_BIT + 2) / 3;
- const char varName[] = "should_not_exist";
+ const char *varName = uniqueEnvVarName.constData();
QFETCH(QByteArray, value);
QFETCH(qint64, expected);
diff --git a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
index 0b65673c393..bbcc8c5e5e1 100644
--- a/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
+++ b/tests/auto/corelib/global/qglobal/tst_qglobal.cpp
@@ -464,7 +464,7 @@ Q_COREAPP_STARTUP_FUNCTION(myStartupFunc)
void tst_QGlobal::qCoreAppStartupFunction()
{
- QCOMPARE(qStartupFunctionValue, 0);
+ qStartupFunctionValue = 0;
int argc = 1;
char *argv[] = { const_cast<char*>(QTest::currentAppName()) };
QCoreApplication app(argc, argv);
diff --git a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
index d2fee5124db..34c0fd11bed 100644
--- a/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
+++ b/tests/auto/corelib/global/qnumeric/tst_qnumeric.cpp
@@ -1011,7 +1011,7 @@ SUB_OVERFLOW_UNSIGNED_TYPE_TEST(ulong, ULONG_MAX)
#if defined(QT_HAS_128_BIT_MULTIPLICATION)
// Compiling this causes an ICE in MSVC, so skipping it
-#if !defined(Q_CC_MSVC) || Q_CC_MSVC > 1944
+#if !defined(Q_CC_MSVC) || Q_CC_MSVC > 1950
SIGNED_TYPE_TEST(qlonglong, LLONG_MIN, LLONG_MAX)
UNSIGNED_TYPE_TEST(qulonglong, ULLONG_MAX)
#endif
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index e0f677e1511..7603d84623b 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -1623,6 +1623,8 @@ void tst_QDebug::threadSafety() const
#ifdef Q_OS_WASM
QSKIP("threadSafety does not run on wasm");
#else
+ s_messages = {};
+
MessageHandlerSetter mhs(threadSafeMessageHandler);
const int numThreads = 10;
QThreadPool::globalInstance()->setMaxThreadCount(numThreads);
diff --git a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
index 0fd62d40f62..9aa99a1b653 100644
--- a/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
+++ b/tests/auto/corelib/io/qloggingregistry/tst_qloggingregistry.cpp
@@ -186,6 +186,12 @@ private slots:
Q_ASSERT(!qApp); // Rules should not require an app to resolve
+ static bool calledOnce = false;
+ if (calledOnce)
+ QSKIP("QLoggingRegistry_environment can only run once");
+
+ calledOnce = true;
+
qputenv("QT_LOGGING_RULES", "qt.foo.bar=true");
QLoggingCategory qtEnabledByLoggingRule("qt.foo.bar");
QCOMPARE(qtEnabledByLoggingRule.isDebugEnabled(), true);
diff --git a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
index 458cdece514..dceb1e3bf66 100644
--- a/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
+++ b/tests/auto/corelib/io/qsavefile/tst_qsavefile.cpp
@@ -55,6 +55,8 @@ class tst_QSaveFile : public QObject
public slots:
private slots:
+ void basics();
+ void stdfilesystem();
void transactionalWrite();
void retryTransactionalWrite();
void textStreamManualFlush();
@@ -91,6 +93,43 @@ static inline QByteArray msgCannotOpen(const QFileDevice &f)
return result.toLocal8Bit();
}
+void tst_QSaveFile::basics()
+{
+ QSaveFile f;
+ QCOMPARE(f.fileName(), QString());
+ f.setFileName("foobar");
+ QCOMPARE(f.fileName(), "foobar");
+ f.setFileName(QString());
+ QCOMPARE(f.fileName(), QString());
+
+ QString abspath = QDir::currentPath() + "/foobar";
+ QSaveFile f2(abspath);
+ QCOMPARE(f2.fileName(), abspath);
+ f2.setFileName(QString());
+ QCOMPARE(f2.fileName(), QString());
+}
+
+void tst_QSaveFile::stdfilesystem()
+{
+#if QT_CONFIG(cxx17_filesystem)
+ using namespace std::filesystem;
+ QSaveFile f;
+ f.setFileName(path("foobar"));
+ QCOMPARE(f.fileName(), "foobar");
+ QCOMPARE(f.filesystemFileName(), path("foobar"));
+ f.setFileName(path());
+ QCOMPARE(f.fileName(), QString());
+ QVERIFY(f.filesystemFileName().empty());
+
+ path abspath = QDir::current().filesystemAbsolutePath() / "foobar";
+ QSaveFile f2(abspath);
+ QCOMPARE(f2.filesystemFileName(), abspath);
+ f2.setFileName(path());
+ QCOMPARE(f2.fileName(), QString());
+ QVERIFY(f.filesystemFileName().empty());
+#endif
+}
+
void tst_QSaveFile::transactionalWrite()
{
QTemporaryDir dir;
diff --git a/tests/auto/corelib/itemmodels/CMakeLists.txt b/tests/auto/corelib/itemmodels/CMakeLists.txt
index 15c32b7a6f2..8304fa15bc6 100644
--- a/tests/auto/corelib/itemmodels/CMakeLists.txt
+++ b/tests/auto/corelib/itemmodels/CMakeLists.txt
@@ -2,8 +2,8 @@
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(qstringlistmodel)
-add_subdirectory(qrangemodel)
if(TARGET Qt::Gui)
+ add_subdirectory(qrangemodel)
add_subdirectory(qabstractitemmodel)
if(QT_FEATURE_proxymodel)
add_subdirectory(qabstractproxymodel)
diff --git a/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp
index 96bbd60ab83..9a5e2a5f89b 100644
--- a/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp
+++ b/tests/auto/corelib/kernel/qchronotimer/tst_qchronotimer.cpp
@@ -326,7 +326,7 @@ void tst_QChronoTimer::remainingTimeDuringActivation()
if (!singleShot) {
// do it again - see QTBUG-46940
- remainingTime = std::chrono::milliseconds::min();
+ remainingTime = std::chrono::nanoseconds::min();
QVERIFY(timeoutSpy.wait());
QCOMPARE_LE(remainingTime, timeout);
QCOMPARE_GT(remainingTime, 0ns);
diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp
index bde70e32233..10769165ec4 100644
--- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp
+++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp
@@ -307,6 +307,13 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(EnumFlagsTester::TestFlags)
void tst_QMetaProperty::readAndWriteWithLazyRegistration()
{
+ static bool executedOnce = false;
+ if (executedOnce) {
+ QSKIP("lazy registration only runs once per type per process");
+ return;
+ }
+ executedOnce = true;
+
QVERIFY(!QMetaType::fromName("CustomReadObject*").isValid());
QVERIFY(!QMetaType::fromName("CustomWriteObject*").isValid());
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
index 683025fd409..3cf16367777 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.cpp
@@ -528,11 +528,25 @@ void tst_QMetaType::qMetaTypeId()
QCOMPARE(::qMetaTypeId<qint8>(), QMetaType::fromType<qint8>().id());
}
+class QPropObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
+
+public:
+ QPropObject() { propList << 42 << "Hello"; }
+
+ QList<QVariant> prop() const { return propList; }
+ void setProp(const QList<QVariant> &list) { propList = list; }
+ QList<QVariant> propList;
+};
+
void tst_QMetaType::properties()
{
qRegisterMetaType<QList<QVariant> >("QList<QVariant>");
+ QPropObject sut;
- QVariant v = property("prop");
+ QVariant v = sut.property("prop");
QCOMPARE(v.typeName(), "QVariantList");
@@ -542,8 +556,8 @@ void tst_QMetaType::properties()
values << 43 << "world";
- QVERIFY(setProperty("prop", values));
- v = property("prop");
+ QVERIFY(sut.setProperty("prop", values));
+ v = sut.property("prop");
QCOMPARE(v.toList().size(), 4);
}
@@ -1450,6 +1464,11 @@ void tst_QMetaType::defaultConstructTrivial_QTBUG_109594()
void tst_QMetaType::typedConstruct()
{
+ static bool calledOnce = false;
+ if (calledOnce)
+ QSKIP("tst_QMetaType::typedConstruct can only run once");
+ calledOnce = true;
+
auto testMetaObjectWriteOnGadget = [](QVariant &gadget, const QList<GadgetPropertyType> &properties)
{
auto metaObject = QMetaType(gadget.userType()).metaObject();
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
index 6f218bb0651..e9a177356e6 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype.h
@@ -25,7 +25,6 @@ struct MessageHandlerCustom : public MessageHandler
class tst_QMetaType: public QObject
{
Q_OBJECT
- Q_PROPERTY(QList<QVariant> prop READ prop WRITE setProp)
public:
struct GadgetPropertyType {
@@ -34,14 +33,8 @@ public:
QVariant testData;
};
- tst_QMetaType() { propList << 42 << "Hello"; }
-
- QList<QVariant> prop() const { return propList; }
- void setProp(const QList<QVariant> &list) { propList = list; }
-
private:
void registerGadget(const char * name, const QList<GadgetPropertyType> &gadgetProperties);
- QList<QVariant> propList;
private slots:
#if QT_CONFIG(thread)
diff --git a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
index 661c1f6072b..93f23259745 100644
--- a/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
+++ b/tests/auto/corelib/kernel/qmetatype/tst_qmetatype2.cpp
@@ -148,6 +148,11 @@ void registerCustomTypeConversions()
void tst_QMetaType::convertCustomType_data()
{
+ static bool calledOnce = false;
+ if (calledOnce)
+ QSKIP("convertCustomType can only run once");
+ calledOnce = true;
+
customTypeNotYetConvertible();
registerCustomTypeConversions();
@@ -363,6 +368,11 @@ void tst_QMetaType::compareCustomEqualOnlyType()
void tst_QMetaType::customDebugStream()
{
+ static bool calledOnce = false;
+ if (calledOnce)
+ QSKIP("customDebugStream can only run once");
+ calledOnce = true;
+
MessageHandlerCustom handler(::qMetaTypeId<CustomDebugStreamableType>());
QVariant v1 = QVariant::fromValue(CustomDebugStreamableType());
handler.expectedMessage = "QVariant(CustomDebugStreamableType, string-content)";
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index afb0bf0169a..6d9f7d12dcb 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -8736,6 +8736,9 @@ QT_END_NAMESPACE
void tst_QObject::emitToDestroyedClass()
{
using namespace EmitToDestroyedClass;
+ assertionCallCount = 0;
+ wouldHaveAssertedCount = 0;
+
std::unique_ptr ptr = std::make_unique<Derived>();
QObject::connect(ptr.get(), &Base::theSignal, ptr.get(), &Derived::doNothing);
QCOMPARE(assertionCallCount, 0);
diff --git a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
index 81316b061d0..98c184872f9 100644
--- a/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
+++ b/tests/auto/corelib/kernel/qtimer/tst_qtimer.cpp
@@ -1202,10 +1202,10 @@ void tst_QTimer::singleShotDestructionBeforeEventDispatcher()
// would be deleted by the QObject destructor, which is too late to
// unregister the timer.
- auto thr = QThread::create([] {
+ std::unique_ptr<QThread> thr{QThread::create([] {
QObject o;
QTimer::singleShot(300s, &o, [] {});
- });
+ })};
thr->start();
thr->wait();
}
diff --git a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
index bef43091277..e713901101c 100644
--- a/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
+++ b/tests/auto/corelib/kernel/qvariant/tst_qvariant.cpp
@@ -455,7 +455,6 @@ private:
};
const qlonglong intMax1 = (qlonglong)INT_MAX + 1;
-const qulonglong uintMax1 = (qulonglong)UINT_MAX + 1;
void tst_QVariant::constructor()
{
@@ -5737,22 +5736,24 @@ void tst_QVariant::sequentialIterableAppend()
void tst_QVariant::preferDirectConversionOverInterfaces()
{
using namespace QtMetaTypePrivate;
- bool calledCorrectConverter = false;
+ static bool calledCorrectConverter = false;
+ calledCorrectConverter = false;
+
QMetaType::registerConverter<MyType, QSequentialIterable>([](const MyType &) {
return QSequentialIterable {};
});
- QMetaType::registerConverter<MyType, QVariantList>([&calledCorrectConverter](const MyType &) {
+ QMetaType::registerConverter<MyType, QVariantList>([&](const MyType &) {
calledCorrectConverter = true;
return QVariantList {};
});
QMetaType::registerConverter<MyType, QAssociativeIterable>([](const MyType &) {
return QAssociativeIterable {};
});
- QMetaType::registerConverter<MyType, QVariantHash>([&calledCorrectConverter](const MyType &) {
+ QMetaType::registerConverter<MyType, QVariantHash>([&](const MyType &) {
calledCorrectConverter = true;
return QVariantHash {};
});
- QMetaType::registerConverter<MyType, QVariantMap>([&calledCorrectConverter](const MyType &) {
+ QMetaType::registerConverter<MyType, QVariantMap>([&](const MyType &) {
calledCorrectConverter = true;
return QVariantMap {};
});
@@ -5783,6 +5784,11 @@ struct MyTypeView
void tst_QVariant::mutableView()
{
+ static bool calledOnce = false;
+ if (calledOnce)
+ QSKIP("This test can only be run once per test execution because of QMetaType registration");
+ calledOnce = true;
+
bool calledView = false;
const bool success = QMetaType::registerMutableView<MyType, MyTypeView>([&](MyType &data) {
calledView = true;
@@ -5906,6 +5912,11 @@ void tst_QVariant::moveOperations()
class NoMetaObject : public QObject {};
void tst_QVariant::equalsWithoutMetaObject()
{
+ static bool calledOnce = false;
+ if (calledOnce)
+ QSKIP("This test can only be run once per test execution because of QMetaType registration");
+ calledOnce = true;
+
using T = NoMetaObject*;
QtPrivate::QMetaTypeInterface d = {
/*.revision=*/ 0,
@@ -6021,6 +6032,12 @@ void tst_QVariant::constructFromIncompatibleMetaType()
void tst_QVariant::constructFromQtLT65MetaType()
{
+ static bool calledOnce = false;
+ if (calledOnce)
+ QSKIP("This test can only be run once per test execution because of QMetaType registration");
+ calledOnce = true;
+
+
auto qsizeIface = QtPrivate::qMetaTypeInterfaceForType<QSize>();
QtPrivate::QMetaTypeInterface qsize64Iface = {
diff --git a/tests/auto/corelib/plugin/CMakeLists.txt b/tests/auto/corelib/plugin/CMakeLists.txt
index 5518231ace2..82fa9d18749 100644
--- a/tests/auto/corelib/plugin/CMakeLists.txt
+++ b/tests/auto/corelib/plugin/CMakeLists.txt
@@ -7,7 +7,9 @@ endif()
add_subdirectory(quuid)
if(QT_FEATURE_library)
add_subdirectory(qpluginloader)
- add_subdirectory(qlibrary)
+ if(QT_FEATURE_private_tests)
+ add_subdirectory(qlibrary)
+ endif()
endif()
if(QT_BUILD_SHARED_LIBS AND QT_FEATURE_library)
add_subdirectory(qplugin)
diff --git a/tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt b/tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt
index fc452f37f53..62dd4a06c17 100644
--- a/tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt
+++ b/tests/auto/corelib/plugin/qlibrary/tst/CMakeLists.txt
@@ -13,7 +13,7 @@ qt_internal_add_test(tst_qlibrary
SOURCES
../tst_qlibrary.cpp
TESTDATA ${test_data}
- LIBRARIES mylib mylib2
+ LIBRARIES mylib mylib2 Qt::CorePrivate
)
add_dependencies(tst_qlibrary mylib mylib2)
diff --git a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
index 5ae49ff1707..d708f6def1c 100644
--- a/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
+++ b/tests/auto/corelib/plugin/qlibrary/tst_qlibrary.cpp
@@ -6,6 +6,7 @@
#include <qdir.h>
#include <qlibrary.h>
#include <QtCore/QRegularExpression>
+#include <QtCore/private/qlibrary_p.h>
// Helper macros to let us know if some suffixes and prefixes are valid
@@ -162,7 +163,12 @@ void tst_QLibrary::cleanup()
};
for (const auto &entry : libs) {
- do {} while (QLibrary(entry.name, entry.version).unload());
+ bool unloaded = false;
+ do {
+ QLibrary lib(entry.name, entry.version);
+ auto libPrivate = QLibraryPrivate::get(&lib);
+ unloaded = libPrivate->unload();
+ } while (unloaded);
}
}
diff --git a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp
index e0173412339..a6662878786 100644
--- a/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp
+++ b/tests/auto/corelib/text/qbytearray/tst_qbytearray.cpp
@@ -2484,6 +2484,10 @@ void tst_QByteArray::fromPercentEncoding()
QFETCH(QByteArray, decodedString);
QCOMPARE(encodedString.percentDecoded(), decodedString);
+ QCOMPARE(QByteArray::fromPercentEncoding(encodedString), decodedString);
+ QCOMPARE(QByteArray{encodedString}.percentDecoded(), decodedString); // rvalue, shared
+ encodedString.detach();
+ QCOMPARE(std::move(encodedString).percentDecoded(), decodedString); // rvalue, detached
}
void tst_QByteArray::toPercentEncoding_data()
@@ -2545,6 +2549,9 @@ void tst_QByteArray::pecentEncodingRoundTrip()
QByteArray encodedData = original.toPercentEncoding(excludeInEncoding, includeInEncoding);
QCOMPARE(encodedData, encoded);
QCOMPARE(encodedData.percentDecoded(), original);
+ QCOMPARE(QByteArray{encodedData}.percentDecoded(), original); // rvalue, shared
+ encodedData.detach();
+ QCOMPARE(std::move(encodedData).percentDecoded(), original); // rvalue, detached
}
struct StringComparisonData
diff --git a/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp b/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp
index 22bff24eec0..c0a67840c75 100644
--- a/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp
+++ b/tests/auto/corelib/text/qstringiterator/tst_qstringiterator.cpp
@@ -11,6 +11,8 @@ class tst_QStringIterator : public QObject
private slots:
void sweep_data();
void sweep();
+ void nextOrRawCodeUnitEquivalenceWithOldCode_data() { sweep_data(); }
+ void nextOrRawCodeUnitEquivalenceWithOldCode();
void position();
};
@@ -253,6 +255,65 @@ void tst_QStringIterator::sweep()
}
}
+void tst_QStringIterator::nextOrRawCodeUnitEquivalenceWithOldCode()
+{
+ QFETCH(const QString, string);
+ // QFETCH(bool, valid);
+
+ const auto s = string.data_ptr().data(); // avoids QChar
+
+ // this is the old code, used before we had nextOrRawCodeUnit():
+ const auto oldResult = [&] {
+ QList<char32_t> result;
+ result.reserve(string.size());
+
+ const auto len = string.size();
+ for (qsizetype i = 0; i < len; ++i) {
+ QT_WARNING_PUSH
+ QT_WARNING_DISABLE_CLANG("-Wcharacter-conversion")
+ char32_t ucs4;
+ const char16_t c = s[i];
+ if (QChar::isHighSurrogate(c) && i + 1 < len && QChar::isLowSurrogate(s[i + 1]))
+ ucs4 = QChar::surrogateToUcs4(c, s[++i]);
+ else
+ ucs4 = c;
+ QT_WARNING_POP
+ result.push_back(ucs4);
+ }
+ return result;
+ }();
+
+ // now the same with nextOrRawCodeUnit():
+ const auto newResult = [&] {
+ QList<char32_t> result;
+ result.reserve(string.size());
+
+ QStringIterator it(string);
+ while (it.hasNext())
+ result.push_back(it.nextOrRawCodeUnit());
+
+ return result;
+ }();
+
+ // they should yield the equivalent series of code points:
+ QCOMPARE_EQ(newResult, oldResult);
+
+ // also check next/previousOrRawCodeUnit() consistency:
+ const auto fromBack = [&] {
+ QList<char32_t> result;
+ result.reserve(string.size());
+
+ QStringIterator it(string, string.size());
+ while (it.hasPrevious())
+ result.push_back(it.previousOrRawCodeUnit());
+
+ std::reverse(result.begin(), result.end());
+ return result;
+ }();
+
+ QCOMPARE_EQ(fromBack, newResult);
+}
+
void tst_QStringIterator::position()
{
static const QChar stringData[] =
diff --git a/tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp b/tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp
index abb7497928a..a6a0ef2f26d 100644
--- a/tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp
+++ b/tests/auto/corelib/text/qunicodetools/tst_qunicodetools.cpp
@@ -12,6 +12,7 @@ class tst_QUnicodeTools : public QObject
{
Q_OBJECT
private slots:
+ void allSurrogatesHaveLineBreakClassSG();
void lineBreakClass();
void graphemeBreakClass_data();
void graphemeBreakClass();
@@ -21,6 +22,17 @@ private slots:
void sentenceBreakClass();
};
+void tst_QUnicodeTools::allSurrogatesHaveLineBreakClassSG()
+{
+ char32_t c;
+ auto printOnFail = qScopeGuard([&] { qDebug() << c; });
+ for (c = 0; c <= QChar::LastValidCodePoint; ++c) {
+ if (QChar::isSurrogate(c))
+ QCOMPARE_EQ(QUnicodeTables::lineBreakClass(c), QUnicodeTables::LineBreak_SG);
+ }
+ printOnFail.dismiss();
+}
+
void tst_QUnicodeTools::lineBreakClass()
{
QVERIFY(QUnicodeTables::lineBreakClass(0x0029) == QUnicodeTables::LineBreak_CP);
diff --git a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp
index 37e1f744f34..763ec71e277 100644
--- a/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp
+++ b/tests/auto/corelib/thread/qthreadonce/tst_qthreadonce.cpp
@@ -80,6 +80,14 @@ QSingleton<SingletonObject> IncrementThread::singleton;
void tst_QThreadOnce::sameThread_data()
{
+ static bool executedOnce = false;
+ if (executedOnce) {
+ QSKIP("tst_QThreadOnce can only run once");
+ return;
+ }
+ executedOnce = true;
+
+
SingletonObject::runCount = 0;
QTest::addColumn<int>("expectedValue");
@@ -105,6 +113,14 @@ void tst_QThreadOnce::sameThread()
void tst_QThreadOnce::multipleThreads()
{
+ static bool executedOnce = false;
+ if (executedOnce) {
+ QSKIP("tst_QThreadOnce can only run once");
+ return;
+ }
+ executedOnce = true;
+
+
#if defined(Q_OS_VXWORKS)
const int NumberOfThreads = 20;
#else
@@ -136,6 +152,13 @@ void tst_QThreadOnce::multipleThreads()
void tst_QThreadOnce::nesting()
{
+ static bool executedOnce = false;
+ if (executedOnce) {
+ QSKIP("tst_QThreadOnce can only run once");
+ return;
+ }
+ executedOnce = true;
+
int variable = 0;
Q_ONCE {
Q_ONCE {
@@ -148,6 +171,14 @@ void tst_QThreadOnce::nesting()
static void reentrant(int control, int &counter)
{
+ static bool executedOnce = false;
+ if (executedOnce) {
+ QSKIP("tst_QThreadOnce can only run once");
+ return;
+ }
+ executedOnce = true;
+
+
Q_ONCE {
if (counter)
reentrant(--control, counter);
@@ -159,6 +190,13 @@ static void reentrant(int control, int &counter)
void tst_QThreadOnce::reentering()
{
+ static bool executedOnce = false;
+ if (executedOnce) {
+ QSKIP("tst_QThreadOnce can only run once");
+ return;
+ }
+ executedOnce = true;
+
const int WantedRecursions = 5;
int count = 0;
SingletonObject::runCount = 0;
@@ -181,6 +219,14 @@ static void exception_helper(int &val)
#ifndef QT_NO_EXCEPTIONS
void tst_QThreadOnce::exception()
{
+ static bool executedOnce = false;
+ if (executedOnce) {
+ QSKIP("tst_QThreadOnce can only run once");
+ return;
+ }
+ executedOnce = true;
+
+
int count = 0;
try {
diff --git a/tests/auto/corelib/time/CMakeLists.txt b/tests/auto/corelib/time/CMakeLists.txt
index 1fb95e9245c..fe249d3c4a5 100644
--- a/tests/auto/corelib/time/CMakeLists.txt
+++ b/tests/auto/corelib/time/CMakeLists.txt
@@ -8,6 +8,4 @@ if(QT_FEATURE_datetimeparser)
add_subdirectory(qdatetimeparser)
endif()
add_subdirectory(qtime)
-if(QT_FEATURE_timezone)
- add_subdirectory(qtimezone)
-endif()
+add_subdirectory(qtimezone)
diff --git a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
index fde06d2edd9..1e9aeeef799 100644
--- a/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
+++ b/tests/auto/corelib/time/qdatetime/tst_qdatetime.cpp
@@ -1262,8 +1262,7 @@ void tst_QDateTime::toString_strformat()
QCOMPARE(testDateTime.toString(u"yyyy-MM-dd hh:mm:ss tt"), u"2013-01-01 01:02:03 +0000"_s);
QCOMPARE(testDateTime.toString(u"yyyy-MM-dd hh:mm:ss ttt"), u"2013-01-01 01:02:03 +00:00"_s);
-#if QT_CONFIG(icu) && !defined(Q_STL_DINKUMWARE)
- // The Dinkum (VxWorks) exception may just be because it has an old ICU.
+#if QT_CONFIG(icu)
// Hopefully other timezone backends shall eventually agree with this:
const QString longForm = u"2013-01-01 01:02:03 Coordinated Universal Time"_s;
#else
diff --git a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
index 6a72b5ddf38..0718d8b637d 100644
--- a/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
+++ b/tests/auto/corelib/time/qtimezone/tst_qtimezone.cpp
@@ -3,7 +3,9 @@
#include <QTest>
#include <qtimezone.h>
-#include <private/qtimezoneprivate_p.h>
+#if QT_CONFIG(timezone)
+# include <private/qtimezoneprivate_p.h>
+#endif
#include <private/qcomparisontesthelper_p.h>
#include <qlocale.h>
@@ -71,8 +73,8 @@ private Q_SLOTS:
#endif // timezone backends
private:
- void printTimeZone(const QTimeZone &tz);
#if QT_CONFIG(timezone)
+ void printTimeZone(const QTimeZone &tz);
# if defined(QT_BUILD_INTERNAL)
// Generic tests of privates, called by implementation-specific private tests:
void testCetPrivate(const QTimeZonePrivate &tzp);
@@ -102,6 +104,7 @@ private:
static constexpr bool debug = false;
};
+#if QT_CONFIG(timezone)
void tst_QTimeZone::printTimeZone(const QTimeZone &tz)
{
QDateTime now = QDateTime::currentDateTime();
@@ -167,9 +170,11 @@ void tst_QTimeZone::printTimeZone(const QTimeZone &tz)
qDebug() << "Transition before 1 Jun = " << tz.previousTransition(jun).atUtc;
qDebug() << "";
}
+#endif // feature timezone
void tst_QTimeZone::createTest()
{
+#if QT_CONFIG(timezone)
const QTimeZone tz("Pacific/Auckland");
if constexpr (debug)
@@ -265,13 +270,16 @@ void tst_QTimeZone::createTest()
QCOMPARE(result.at(i).daylightTimeOffset, expected.at(i).daylightTimeOffset);
}
}
+#else
+ QSKIP("Test depends on backends, enabled by feature timezone");
+#endif // feature timezone
}
void tst_QTimeZone::nullTest()
{
QTimeZone nullTz1;
QTimeZone nullTz2;
- QTimeZone utc("UTC");
+ QTimeZone utc(QTimeZone::UTC);
// Validity tests
QCOMPARE(nullTz1.isValid(), false);
@@ -290,6 +298,7 @@ void tst_QTimeZone::nullTest()
utc = nullTz1;
QCOMPARE(utc.isValid(), false);
+#if QT_CONFIG(timezone)
QCOMPARE(nullTz1.id(), QByteArray());
QCOMPARE(nullTz1.territory(), QLocale::AnyTerritory);
QCOMPARE(nullTz1.comment(), QString());
@@ -335,6 +344,7 @@ void tst_QTimeZone::nullTest()
QCOMPARE(data.offsetFromUtc, invalidOffset);
QCOMPARE(data.standardTimeOffset, invalidOffset);
QCOMPARE(data.daylightTimeOffset, invalidOffset);
+#endif // feature timezone
}
void tst_QTimeZone::assign()
@@ -487,7 +497,7 @@ void tst_QTimeZone::offset()
void tst_QTimeZone::dataStreamTest()
{
-#ifndef QT_NO_DATASTREAM
+#if QT_CONFIG(timezone) && !defined(QT_NO_DATASTREAM)
// Test the OffsetFromUtc backend serialization. First with a custom timezone:
QTimeZone tz1("QST"_ba, 23456,
u"Qt Standard Time"_s, u"QST"_s, QLocale::Norway, u"Qt Testing"_s);
@@ -546,7 +556,7 @@ void tst_QTimeZone::dataStreamTest()
QCOMPARE(ds.status(), QDataStream::Ok);
}
QCOMPARE(tz2.id(), tz1.id());
-#endif
+#endif // feature timezone and enabled datastream
}
#if QT_CONFIG(timezone)
@@ -791,7 +801,7 @@ void tst_QTimeZone::hasAlternativeName()
void tst_QTimeZone::specificTransition_data()
{
-#if QT_CONFIG(timezone) && QT_CONFIG(timezone_tzdb) && defined(__GLIBCXX__)
+#if QT_CONFIG(timezone_tzdb) && defined(__GLIBCXX__)
QSKIP("libstdc++'s C++20 misreads the IANA DB for Moscow's transitions (among others).");
#endif
#if defined Q_OS_ANDROID && !QT_CONFIG(timezone_tzdb)
@@ -1408,7 +1418,8 @@ void tst_QTimeZone::utcTest()
void tst_QTimeZone::icuTest()
{
-#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu) && !QT_CONFIG(timezone_tzdb) && !defined(Q_OS_UNIX)
+#if defined(QT_BUILD_INTERNAL) && QT_CONFIG(icu) && !QT_CONFIG(timezone_tzdb) \
+ && (defined(Q_OS_VXWORKS) || !defined(Q_OS_UNIX))
// Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
qint64 dst = QDateTime(QDate(2012, 6, 1), QTime(0, 0), QTimeZone::UTC).toMSecsSinceEpoch();
@@ -1456,8 +1467,9 @@ void tst_QTimeZone::icuTest()
void tst_QTimeZone::tzTest()
{
-#if defined QT_BUILD_INTERNAL && defined Q_OS_UNIX \
- && !QT_CONFIG(timezone_tzdb) && !defined Q_OS_DARWIN && !defined Q_OS_ANDROID
+#if defined QT_BUILD_INTERNAL && defined Q_OS_UNIX \
+ && !(QT_CONFIG(timezone_tzdb) || defined(Q_OS_DARWIN) \
+ || defined(Q_OS_ANDROID) || defined(Q_OS_VXWORKS))
const auto UTC = QTimeZone::UTC;
// Known datetimes
qint64 std = QDateTime(QDate(2012, 1, 1), QTime(0, 0), UTC).toMSecsSinceEpoch();
@@ -1947,7 +1959,7 @@ void tst_QTimeZone::roundtripDisplayNames()
if (!match)
match = QTimeZonePrivate::findLongNamePrefix(extended, locale);
if (!match)
- match = QTimeZonePrivate::findNarrowOffsetPrefix(extended, locale, QLocale::NarrowFormat);
+ match = QTimeZonePrivate::findNarrowOffsetPrefix(extended, locale);
if (!match)
match = QTimeZonePrivate::findLongUtcPrefix(extended);
auto report = qScopeGuard([=]() {
diff --git a/tests/auto/corelib/tools/collections/tst_collections.cpp b/tests/auto/corelib/tools/collections/tst_collections.cpp
index 463f600e36d..cbe04ae39f7 100644
--- a/tests/auto/corelib/tools/collections/tst_collections.cpp
+++ b/tests/auto/corelib/tools/collections/tst_collections.cpp
@@ -650,14 +650,14 @@ QT_WARNING_POP
{
QList<int *> list;
QVERIFY(list.value(0) == 0);
- int i;
+ int i = 42;
list.append(&i);
QVERIFY(list.value(0) == &i);
}
{
QList<const int *> list;
QVERIFY(list.value(0) == 0);
- int i;
+ int i = 42;
list.append(&i);
QVERIFY(list.value(0) == &i);
}
diff --git a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
index 51edf7a1ea7..b671c419b2b 100644
--- a/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
+++ b/tests/auto/corelib/tools/qcommandlineparser/tst_qcommandlineparser.cpp
@@ -17,6 +17,7 @@ class tst_QCommandLineParser : public QObject
public slots:
void initTestCase();
+ void cleanupTestCase();
private slots:
void parsingModes_data();
@@ -71,6 +72,11 @@ void tst_QCommandLineParser::initTestCase()
empty_argv[0] = const_cast<char*>(QTest::currentAppName());
}
+void tst_QCommandLineParser::cleanupTestCase()
+{
+ empty_argv[0] = nullptr;
+}
+
Q_DECLARE_METATYPE(QCommandLineParser::SingleDashWordOptionMode)
void tst_QCommandLineParser::parsingModes_data()
diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
index f7c5af53310..9129fb2e7ed 100644
--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
+++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp
@@ -3244,7 +3244,6 @@ void tst_QWindow::enterLeaveOnWindowShowHide()
QSKIP("We can't move the cursor");
window.show();
- window.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&window));
++expectedEnter;
diff --git a/tests/auto/other/languagechange/tst_languagechange.cpp b/tests/auto/other/languagechange/tst_languagechange.cpp
index 8f99730a192..ab9244c8561 100644
--- a/tests/auto/other/languagechange/tst_languagechange.cpp
+++ b/tests/auto/other/languagechange/tst_languagechange.cpp
@@ -172,10 +172,10 @@ void tst_languageChange::retranslatability_data()
<< "QFileDialog::Back"
<< "QFileDialog::Create New Folder"
<< "QFileDialog::Detail View"
- << "QFileDialog::Files of type:"
+ << "QFileDialog::Files of &type:"
<< "QFileDialog::Forward"
<< "QFileDialog::List View"
- << "QFileDialog::Look in:"
+ << "QFileDialog::&Look in:"
<< "QFileDialog::Open"
<< "QFileDialog::Parent Directory"
<< "QFileDialog::Show "
diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
index bf3efca35b2..764644bb192 100644
--- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
+++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp
@@ -1357,6 +1357,11 @@ void tst_QAccessibility::scrollBarTest()
scrollBar->setMinimum(11);
scrollBar->setMaximum(111);
+ QAccessibleAttributesInterface *attributesIface = scrollBarInterface->attributesInterface();
+ QVERIFY(attributesIface);
+ QVERIFY(attributesIface->attributeKeys().contains(QAccessible::Attribute::Orientation));
+ QCOMPARE(attributesIface->attributeValue(QAccessible::Attribute::Orientation), Qt::Horizontal);
+
QAccessibleValueInterface *valueIface = scrollBarInterface->valueInterface();
QVERIFY(valueIface != 0);
QCOMPARE(valueIface->minimumValue().toInt(), scrollBar->minimum());
@@ -1788,6 +1793,15 @@ void tst_QAccessibility::spinBoxTest()
QAccessibleTextInterface *textIface = interface->textInterface();
QVERIFY(textIface);
+ QVERIFY(!spinBox->isReadOnly());
+ QVERIFY(interface->state().editable);
+ QVERIFY(!interface->state().readOnly);
+
+ spinBox->setReadOnly(true);
+ QVERIFY(spinBox->isReadOnly());
+ QVERIFY(!interface->state().editable);
+ QVERIFY(interface->state().readOnly);
+
QTestAccessibility::clearEvents();
}
@@ -1899,6 +1913,20 @@ void tst_QAccessibility::textEditTest()
QCOMPARE(textIface->textAtOffset(15, QAccessible::LineBoundary, &startOffset, &endOffset), QString("How are you today?"));
QCOMPARE(startOffset, 13);
QCOMPARE(endOffset, 31);
+
+ QCOMPARE(textIface->textAfterOffset(3, QAccessible::WordBoundary, &startOffset, &endOffset),
+ QString("world"));
+ QCOMPARE(
+ textIface->textBeforeOffset(8, QAccessible::WordBoundary, &startOffset, &endOffset),
+ QString("hello"));
+ // no more word before or after the last one
+ QCOMPARE(
+ textIface->textBeforeOffset(1, QAccessible::WordBoundary, &startOffset, &endOffset),
+ QString());
+ QCOMPARE(textIface->textAfterOffset(textIface->characterCount() - 1,
+ QAccessible::WordBoundary, &startOffset, &endOffset),
+ QString());
+
QCOMPARE(textIface->characterCount(), 48);
QFontMetrics fm(edit.document()->defaultFont());
QCOMPARE(textIface->characterRect(0).size(), QSize(fm.horizontalAdvance("h"), fm.height()));
@@ -2316,6 +2344,12 @@ void tst_QAccessibility::lineEditTest()
QCOMPARE(textIface->textAtOffset(5, QAccessible::LineBoundary,&start,&end), cite);
QCOMPARE(textIface->textAtOffset(5, QAccessible::NoBoundary,&start,&end), cite);
+ le3->setText("Hello");
+ QCOMPARE(textIface->textAtOffset(1, QAccessible::WordBoundary, &start, &end),
+ QString::fromLatin1("Hello"));
+ QCOMPARE(textIface->textBeforeOffset(1, QAccessible::WordBoundary, &start, &end), QString());
+ QCOMPARE(textIface->textAfterOffset(1, QAccessible::WordBoundary, &start, &end), QString());
+
QTestAccessibility::clearEvents();
}
diff --git a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
index c1b72d4d623..b4cfb0f4f79 100644
--- a/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
+++ b/tests/auto/other/qfocusevent/tst_qfocusevent.cpp
@@ -364,7 +364,6 @@ void tst_QFocusEvent::checkReason_ActiveWindow()
Window window;
window.show();
- window.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&window));
if (windowActivationReasonFail)
@@ -374,7 +373,6 @@ void tst_QFocusEvent::checkReason_ActiveWindow()
Window window2;
window2.show();
- window2.requestActivate();
QVERIFY(QTest::qWaitForWindowActive(&window2));
if (windowActivationReasonFail)
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
index 5f54471bc0f..df3bf7472d0 100644
--- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -815,9 +815,9 @@ void tst_QFiledialog::labelText()
QFileDialog fd;
QDialogButtonBox buttonBox;
QPushButton *cancelButton = buttonBox.addButton(QDialogButtonBox::Cancel);
- QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("Look in:"));
+ QCOMPARE(fd.labelText(QFileDialog::LookIn), QString("&Look in:"));
QCOMPARE(fd.labelText(QFileDialog::FileName), QString("File &name:"));
- QCOMPARE(fd.labelText(QFileDialog::FileType), QString("Files of type:"));
+ QCOMPARE(fd.labelText(QFileDialog::FileType), QString("Files of &type:"));
QCOMPARE(fd.labelText(QFileDialog::Accept), QString("&Open")); ///### see task 241462
QCOMPARE(fd.labelText(QFileDialog::Reject), cancelButton->text());
diff --git a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
index a79d3454724..e8a3e8c046d 100644
--- a/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog2/tst_qfiledialog2.cpp
@@ -47,6 +47,7 @@ Q_GUI_EXPORT void qt_test_resetFetchedRoot();
QT_END_NAMESPACE
#endif
+[[maybe_unused]]
static QByteArray msgDoesNotExist(const QString &name)
{
return (QLatin1Char('"') + QDir::toNativeSeparators(name)
diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
index b651668cabd..526081b2f19 100644
--- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
+++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp
@@ -2842,15 +2842,6 @@ const bool block_some_signals = true; // The test should also work with this set
const int rowcount = 500;
const int colcount = 10;
-static inline QString istr(int n, bool comma = true)
-{
- QString s;
- s.setNum(n);
- if (comma)
- s += ", ";
- return s;
-}
-
void tst_QHeaderView::setupTestData()
{
QTest::addColumn<bool>("updates_enabled");
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 8e46876934d..e3d172c60c0 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -187,6 +187,7 @@ private slots:
void mapFromAndTo();
void focusChainOnHide();
void focusChainOnReparent();
+ void focusChainOnReparentNoChange();
void focusAbstraction();
void defaultTabOrder();
void reverseTabOrder();
@@ -1983,6 +1984,82 @@ void tst_QWidget::focusChainOnReparent()
}
}
+//#define DEBUG_FOCUS_CHAIN
+static void dumpFocusChain(QWidget *start, bool bForward, const char *desc = nullptr)
+{
+#ifdef DEBUG_FOCUS_CHAIN
+ qDebug() << "Dump focus chain, start:" << start << "isForward:" << bForward << desc;
+ QWidget *cur = start;
+ do {
+ qDebug() << "-" << cur << cur->objectName();
+ auto widgetPrivate = static_cast<QWidgetPrivate *>(qt_widget_private(cur));
+ cur = bForward ? widgetPrivate->focus_next : widgetPrivate->focus_prev;
+ } while (cur != start);
+#else
+ Q_UNUSED(start);
+ Q_UNUSED(bForward);
+ Q_UNUSED(desc);
+#endif
+}
+
+void tst_QWidget::focusChainOnReparentNoChange()
+{
+ QWidget window;
+
+ auto new_QWidget = [](QWidget *parent, const char *name) {
+ QWidget *w = new QWidget(parent);
+ w->setObjectName(name);
+ return w;
+ };
+ QWidget *child1 = new_QWidget(&window, "child1");
+ QWidget *child2 = new_QWidget(&window, "child2");
+ QWidget *child3 = new_QWidget(&window, "child3");
+ QWidget *child21 = new_QWidget(child2, "child21");
+ QWidget *child22 = new_QWidget(child2, "child22");
+ QWidget *child4 = new_QWidget(&window, "child4");
+
+ dumpFocusChain(&window, true);
+
+ QWidget *expectedOriginalChain[8] = {&window, child1, child2, child3, child21, child22, child4, &window};
+ QWidget *w = &window;
+ for (auto expectedOriginal : expectedOriginalChain) {
+ QCOMPARE(w, expectedOriginal);
+ w = w->nextInFocusChain();
+ }
+ for (int i = 7; i >= 0; --i) {
+ w = w->previousInFocusChain();
+ QCOMPARE(w, expectedOriginalChain[i]);
+ }
+
+ child2->setParent(child4);
+ child22->setParent(&window);
+ dumpFocusChain(&window, true);
+
+ /*
+ * child2 and child22 was reparented *within* the &window hierarchy
+ * Hierarchy is now:
+ *
+ * - window
+ * - child1
+ * - child3
+ * - child4
+ * - child2
+ * - child21
+ * - child22
+ *
+ * but focus chain remains the same (it depends on the order of widget construction)
+ */
+ QWidget *expectedNewChain[8] = {&window, child1, child2, child3, child21, child22, child4, &window};
+ w = &window;
+ for (auto expectedNew : expectedNewChain) {
+ QCOMPARE(w, expectedNew);
+ w = w->nextInFocusChain();
+ }
+ for (int i = 7; i >= 0; --i) {
+ w = w->previousInFocusChain();
+ QCOMPARE(w, expectedNewChain[i]);
+ }
+}
void tst_QWidget::focusChainOnHide()
{
@@ -2536,24 +2613,6 @@ void tst_QWidget::tabOrderWithProxyDisabled()
qPrintable(focusWidgetName()));
}
-//#define DEBUG_FOCUS_CHAIN
-static void dumpFocusChain(QWidget *start, bool bForward, const char *desc = nullptr)
-{
-#ifdef DEBUG_FOCUS_CHAIN
- qDebug() << "Dump focus chain, start:" << start << "isForward:" << bForward << desc;
- QWidget *cur = start;
- do {
- qDebug() << "-" << cur;
- auto widgetPrivate = static_cast<QWidgetPrivate *>(qt_widget_private(cur));
- cur = bForward ? widgetPrivate->focus_next : widgetPrivate->focus_prev;
- } while (cur != start);
-#else
- Q_UNUSED(start);
- Q_UNUSED(bForward);
- Q_UNUSED(desc);
-#endif
-}
-
void tst_QWidget::tabOrderWithCompoundWidgets()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index 6859f22c044..10a67daa02a 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -845,12 +845,12 @@ void tst_QComboBox::virtualAutocompletion()
QKeyEvent kp3(QEvent::KeyPress, Qt::Key_R, {}, "r");
QKeyEvent kr3(QEvent::KeyRelease, Qt::Key_R, {}, "r");
- QTest::qWait(QApplication::keyboardInputInterval());
QApplication::sendEvent(testWidget, &kp3);
+ QTest::qWait(QApplication::keyboardInputInterval());
QApplication::sendEvent(testWidget, &kr3);
QTRY_COMPARE(testWidget->currentIndex(), 3);
- QTest::qWait(QApplication::keyboardInputInterval());
+ QTest::qWait(2 * QApplication::keyboardInputInterval());
testWidget->view()->setKeyboardSearchFlags(Qt::MatchContains | Qt::MatchWrap);
QApplication::sendEvent(testWidget, &kp3);
QApplication::sendEvent(testWidget, &kr3);
@@ -2247,10 +2247,11 @@ void tst_QComboBox::ignoreWheelEvents()
QFETCH(bool, allowWheelScrolling);
+ AllowWheelScrollStyle style(allowWheelScrolling);
WheelEventTestWidget widget;
QComboBox *comboBox = new QComboBox(&widget);
comboBox->addItems({ "0", "1" });
- comboBox->setStyle(new AllowWheelScrollStyle(allowWheelScrolling));
+ comboBox->setStyle(&style);
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
diff --git a/tests/manual/CMakeLists.txt b/tests/manual/CMakeLists.txt
index 8ace9592141..ad9db868235 100644
--- a/tests/manual/CMakeLists.txt
+++ b/tests/manual/CMakeLists.txt
@@ -6,7 +6,6 @@ if(UIKIT)
return()
endif()
-add_subdirectory(assets)
add_subdirectory(corelib)
add_subdirectory(filetest)
# diaglib is broken in dev due to missing
diff --git a/tests/manual/assets/CMakeLists.txt b/tests/manual/assets/CMakeLists.txt
deleted file mode 100644
index 03643aa8537..00000000000
--- a/tests/manual/assets/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (C) 2024 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-add_subdirectory(downloader)
diff --git a/tests/manual/assets/assets.pro b/tests/manual/assets/assets.pro
deleted file mode 100644
index 43f09ba46e6..00000000000
--- a/tests/manual/assets/assets.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-TEMPLATE=subdirs
-
-SUBDIRS = downloader
diff --git a/tests/manual/assets/downloader/CMakeLists.txt b/tests/manual/assets/downloader/CMakeLists.txt
deleted file mode 100644
index b95161ac02d..00000000000
--- a/tests/manual/assets/downloader/CMakeLists.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (C) 2024 The Qt Company Ltd.
-# SPDX-License-Identifier: BSD-3-Clause
-
-#####################################################################
-## tst_manual_downloader Binary:
-#####################################################################
-
-qt_internal_add_manual_test(tst_manual_downloader
- GUI
- SOURCES
- main.cpp
- LIBRARIES
- Qt::ExamplesAssetDownloaderPrivate
- Qt::Widgets
-)
diff --git a/tests/manual/assets/downloader/downloader.pro b/tests/manual/assets/downloader/downloader.pro
deleted file mode 100644
index 53976c538f0..00000000000
--- a/tests/manual/assets/downloader/downloader.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-QT += examples_asset_downloader-private widgets
-
-TARGET = tst_manual_downloader
-
-SOURCES += main.cpp
diff --git a/tests/manual/assets/downloader/main.cpp b/tests/manual/assets/downloader/main.cpp
deleted file mode 100644
index d9d711cfce5..00000000000
--- a/tests/manual/assets/downloader/main.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2024 The Qt Company Ltd.
-// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
-
-#include <QtExamplesAssetDownloader/assetdownloader.h>
-
-#include <QApplication>
-#include <QMessageBox>
-#include <QProgressDialog>
-
-using namespace Assets::Downloader;
-
-int main(int argc, char *argv[])
-{
- QApplication app(argc, argv);
- app.setOrganizationName("QtProject");
- app.setApplicationName("Asset Downloader");
-
- QProgressDialog progress;
- progress.setAutoClose(false);
- progress.setRange(0, 0);
- QObject::connect(&progress, &QProgressDialog::canceled, &app, &QApplication::quit);
-
- AssetDownloader downloader;
- downloader.setJsonFileName("car-configurator-assets-v1.json");
- downloader.setZipFileName("car-configurator-assets-v1.zip");
- downloader.setDownloadBase(QUrl("https://download.qt.io/learning/examples/"));
-
- QObject::connect(&downloader, &AssetDownloader::started,
- &progress, &QProgressDialog::show);
- QObject::connect(&downloader, &AssetDownloader::progressChanged, &progress, [&progress](
- int progressValue, int progressMaximum, const QString &progressText) {
- progress.setLabelText(progressText);
- progress.setMaximum(progressMaximum);
- progress.setValue(progressValue);
- });
- QObject::connect(&downloader, &AssetDownloader::finished, &progress, [&](bool success) {
- progress.reset();
- progress.hide();
- if (success)
- QMessageBox::information(nullptr, "Asset Downloader", "Download Finished Successfully.");
- else
- QMessageBox::warning(nullptr, "Asset Downloader", "Download Finished with an Error.");
- });
-
- downloader.start();
-
- return app.exec();
-}
diff --git a/tests/manual/highdpi/pixelgadget/CMakeLists.txt b/tests/manual/highdpi/pixelgadget/CMakeLists.txt
index f808786b2a0..80f40fea352 100644
--- a/tests/manual/highdpi/pixelgadget/CMakeLists.txt
+++ b/tests/manual/highdpi/pixelgadget/CMakeLists.txt
@@ -5,6 +5,12 @@
## pixelgadget Binary:
#####################################################################
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(pixelgadget LANGUAGES C CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_manual_test(pixelgadget
GUI
SOURCES
diff --git a/tests/manual/highdpi/screengadget/CMakeLists.txt b/tests/manual/highdpi/screengadget/CMakeLists.txt
index f4a7aad3067..038ff8fc851 100644
--- a/tests/manual/highdpi/screengadget/CMakeLists.txt
+++ b/tests/manual/highdpi/screengadget/CMakeLists.txt
@@ -5,6 +5,12 @@
## screengadget Binary:
#####################################################################
+if (NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_BUILDING_QT)
+ cmake_minimum_required(VERSION 3.16)
+ project(screengadget LANGUAGES C CXX)
+ find_package(Qt6BuildInternals COMPONENTS STANDALONE_TEST)
+endif()
+
qt_internal_add_manual_test(screengadget
GUI
SOURCES
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
index 47f2ae9bd0f..e28eb5316a8 100644
--- a/tests/manual/manual.pro
+++ b/tests/manual/manual.pro
@@ -2,7 +2,6 @@ TEMPLATE=subdirs
QT_FOR_CONFIG += network-private gui-private
SUBDIRS = \
-assets \
filetest \
embeddedintoforeignwindow \
foreignwindows \
diff --git a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
index 1fd6e0a0c4f..ff3e67e3fc2 100644
--- a/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
+++ b/tests/manual/wasm/eventloop/suspendresumecontrol_auto/main.cpp
@@ -3,6 +3,7 @@
#include <QtCore/qcoreapplication.h>
#include <QtCore/private/qwasmsuspendresumecontrol_p.h>
+#include <QtCore/qdebug.h>
#include <qtwasmtestlib.h>
using namespace emscripten;
@@ -20,6 +21,7 @@ private slots:
void reuseTimer();
void cancelTimer();
void deleteTimer();
+ void suspendExclusive();
};
// Verify that a single timer fires
@@ -138,6 +140,49 @@ void WasmSuspendResumeControlTest::deleteTimer()
QWASMSUCCESS();
}
+// Verify that an exclusive suspend resumes for the exclusive event only
+void WasmSuspendResumeControlTest::suspendExclusive()
+{
+ QWasmSuspendResumeControl suspendResume;
+
+ // (re) implement a native timer - this gives us a unique event handler
+ // index which we can suspend exclusively on.
+ bool exclusiveTimerFired = false;
+ auto exclusiveTimerHandler = [&exclusiveTimerFired](emscripten::val) {
+ exclusiveTimerFired = true;
+ };
+ uint32_t exlusiveTimerHandlerIndex = suspendResume.registerEventHandler(std::move(exclusiveTimerHandler));
+
+ std::chrono::milliseconds exclusiveTimerTimeout = timerTimeout * 4;
+ double timoutValue = static_cast<double>(exclusiveTimerTimeout.count());
+ val jsHandler = suspendResume.jsEventHandlerAt(exlusiveTimerHandlerIndex);
+ val::global("window").call<double>("setTimeout", jsHandler, timoutValue);
+
+ // Schedule suppressedTimer to fire before the exclusive timer. Expected
+ // behavior is that it doesn't.
+ bool suppressedTimerFired = false;
+ QWasmTimer suppressedTimer(&suspendResume, [&suppressedTimerFired](){
+ suppressedTimerFired = true;
+ });
+ suppressedTimer.setTimeout(timerTimeout);
+
+ // Suspend exclusively for the exclusive timer, and verify that
+ // the correct timers fired.
+ suspendResume.suspendExclusive(exlusiveTimerHandlerIndex);
+ suspendResume.sendPendingEvents(); // <- also clears exclusive mode
+ if (!exclusiveTimerFired)
+ QWASMFAIL("Exclusive timer did not fire");
+ if (suppressedTimerFired)
+ QWASMFAIL("Suppressed timer did fire");
+
+ // Send (all) events, this should give is the suppressed timer
+ suspendResume.sendPendingEvents();
+ if (!suppressedTimerFired)
+ QWASMFAIL("Suppressed timer did not fire");
+
+ QWASMSUCCESS();
+}
+
int main(int argc, char **argv)
{
auto testObject = std::make_shared<WasmSuspendResumeControlTest>();
diff --git a/tests/manual/wasm/qtwasmtestlib/qtwasmtestlib.cpp b/tests/manual/wasm/qtwasmtestlib/qtwasmtestlib.cpp
index ec03c7209a4..1e49847c97f 100644
--- a/tests/manual/wasm/qtwasmtestlib/qtwasmtestlib.cpp
+++ b/tests/manual/wasm/qtwasmtestlib/qtwasmtestlib.cpp
@@ -127,7 +127,7 @@ void passTest()
EMSCRIPTEN_BINDINGS(qtwebtestrunner) {
emscripten::function("cleanupTestCase", &cleanupTestCase);
emscripten::function("getTestFunctions", &getTestFunctions);
- emscripten::function("runTestFunction", &runTestFunction);
+ emscripten::function("runTestFunction", &runTestFunction, emscripten::async());
emscripten::function("qtWasmFail", &failTest);
emscripten::function("qtWasmPass", &passTest);
}
diff --git a/util/sbom/cyclonedx/.gitignore b/util/sbom/cyclonedx/.gitignore
new file mode 100644
index 00000000000..140f5f55f12
--- /dev/null
+++ b/util/sbom/cyclonedx/.gitignore
@@ -0,0 +1,6 @@
+__pycache__
+*.egg-info
+.coverage
+.idea
+*.pyc
+build/
diff --git a/util/sbom/cyclonedx/Makefile b/util/sbom/cyclonedx/Makefile
new file mode 100644
index 00000000000..711daf5da22
--- /dev/null
+++ b/util/sbom/cyclonedx/Makefile
@@ -0,0 +1,14 @@
+lint: check format_check
+
+env:
+ uv sync
+
+check:
+ uvx ruff check
+ uvx pyright
+
+format:
+ uvx ruff format
+
+format_check:
+ uvx ruff format --check
diff --git a/util/sbom/cyclonedx/README.md b/util/sbom/cyclonedx/README.md
new file mode 100644
index 00000000000..3a6394f4e74
--- /dev/null
+++ b/util/sbom/cyclonedx/README.md
@@ -0,0 +1,54 @@
+# Qt CycloneDX SBOM helper tool
+
+This repository contains a Python script to create a CycloneDX Software
+Bill of Materials (SBOM) document for Qt-based projects.
+
+## Requirements
+
+- [Python 3.9](https://www.python.org/downloads/),
+- `pip` to manage Python packages.
+- [cyclonedx-python-lib package](https://pypi.org/project/cyclonedx-python-lib/) can be installed via pip
+- optional [tomli package](https://pypi.org/project/tomli/) if using Python 3.9 and the vendored
+ tomli package is causing issues
+
+```sh
+pip install 'cyclonedx-python-lib[json-validation]' tomli
+```
+or
+```
+pip install . # in the current directory to parse the `pyproject.toml` dependencies
+```
+
+## Description
+
+The tool is not meant to be run standalone. Instead, the Qt CMake build system generates an
+intermediate TOML file during the build process, which is then processed by the provided Python
+script to create the final CycloneDX SBOM in JSON format.
+
+## Development
+
+The script is using [uv](https://docs.astral.sh/uv/getting-started/installation/) to manage
+a virtual environment for development. Install it before running the commands below.
+
+Run
+
+```sh
+# Create a virtual environment with with the project dependencies using `uv` in the current dir
+make env
+
+# Optionally install the package in editable mode, for IDE support if needed.
+uv pip install -e .
+
+# Run the script
+python ./qt_cyclonedx_generator/qt_cyclonedx_generator.py
+```
+
+To format the source code run:
+```sh
+make format # uses uvx ruff format
+```
+
+To run the lints:
+```sh
+make lint # uses uvx ruff check and pyright
+```
diff --git a/util/sbom/cyclonedx/pyproject.toml b/util/sbom/cyclonedx/pyproject.toml
new file mode 100644
index 00000000000..19500012555
--- /dev/null
+++ b/util/sbom/cyclonedx/pyproject.toml
@@ -0,0 +1,54 @@
+[project]
+name = "qt-cyclonedx-generator"
+version = "0.1.0"
+description = "Tool to generate a CycloneDX v1.6 SBOM for a Qt project."
+readme = "README.md"
+
+requires-python = ">=3.9"
+
+dependencies = [
+ "cyclonedx-python-lib[json-validation]>=10.0.0",
+ 'tomli ; python_version < "3.11"'
+]
+
+# Development dependencies.
+[dependency-groups]
+dev = [
+ "setuptools>=65",
+ "ruff>=0.11.2",
+ "tomli>=2.3.0",
+ "pyright>=1.1.406",
+]
+
+[project.scripts]
+qt_cyclonedx_generator = "qt_cyclonedx_generator.qt_cyclonedx_generator:main"
+
+[build-system]
+requires = ["setuptools"]
+build-backend = "setuptools.build_meta"
+
+[tool.ruff.lint]
+ignore = ["E402"]
+
+[tool.pyright]
+# To find the imports created by uv
+venvPath = "."
+venv = ".venv"
+
+# Exclude the default folders, plus the build one.
+exclude = [
+ "**/node_modules",
+ "**/__pycache__",
+ "**/.*",
+ "build/*",
+]
+
+# Because some of the toml libraries might not be found
+reportMissingImports = "none"
+
+# Strict is too strict.
+typeCheckingMode = "basic"
+
+pythonVersion = "3.9"
+pythonPlatform = "All"
+
diff --git a/util/sbom/cyclonedx/qt_cyclonedx_generator/__init__.py b/util/sbom/cyclonedx/qt_cyclonedx_generator/__init__.py
new file mode 100644
index 00000000000..50aa992f8ba
--- /dev/null
+++ b/util/sbom/cyclonedx/qt_cyclonedx_generator/__init__.py
@@ -0,0 +1,2 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
diff --git a/util/sbom/cyclonedx/qt_cyclonedx_generator/qt_cyclonedx_generator.py b/util/sbom/cyclonedx/qt_cyclonedx_generator/qt_cyclonedx_generator.py
new file mode 100644
index 00000000000..3b04a47d714
--- /dev/null
+++ b/util/sbom/cyclonedx/qt_cyclonedx_generator/qt_cyclonedx_generator.py
@@ -0,0 +1,881 @@
+# Copyright (C) 2025 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+import importlib.util
+import logging
+import sys
+
+
+def setup_log() -> logging.Logger:
+ logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
+ log_object = logging.getLogger("qt-cyclonedx-generator")
+ log_object.setLevel(logging.INFO)
+ return log_object
+
+
+log = setup_log()
+
+
+def import_tomllib():
+ """Import the TOML library with fallback options for different Python versions.
+
+ Stock toml lib is available on Python 3.11+,
+ if not found try the tomli library, and if that isn't found
+ try to use the pip vendored tomli library.
+
+ Returns:
+ Tuple of (tomllib_module, success_flag)
+ """
+ if sys.version_info >= (3, 11):
+ import tomllib as tomllib_local
+
+ return tomllib_local, True
+ else:
+ try:
+ import tomli as tomllib_local
+
+ return tomllib_local, True
+ except ModuleNotFoundError:
+ try: # noinspection PyProtectedMember
+ import pip._vendor.tomli as tomllib_local
+
+ return tomllib_local, True
+ except ModuleNotFoundError:
+ return None, False
+
+
+tomllib, tomllib_available = import_tomllib()
+
+
+def check_package_dependencies() -> None:
+ """Check if required package dependencies are available."""
+ missing_packages = []
+
+ if not tomllib_available:
+ missing_packages.append("tomli")
+
+ if importlib.util.find_spec("cyclonedx") is None:
+ missing_packages.append("cyclonedx")
+
+ if importlib.util.find_spec("packageurl") is None:
+ missing_packages.append("packageurl")
+
+ if missing_packages:
+ log.error(f"Missing required dependencies: {', '.join(missing_packages)}")
+ log.error(f"Please install with: `pip install {' '.join(missing_packages)}`")
+ sys.exit(1)
+
+
+check_package_dependencies()
+
+import argparse
+from datetime import datetime, timezone
+from license_expression import get_spdx_licensing
+from pathlib import Path
+from packageurl import PackageURL
+from typing import (
+ TYPE_CHECKING,
+ Optional,
+ Any,
+ TypedDict,
+ Union,
+ cast,
+ Callable,
+)
+from uuid import UUID
+
+from cyclonedx.factory.license import LicenseFactory
+from cyclonedx.exception import MissingOptionalDependencyException
+from cyclonedx.model import (
+ XsUri,
+ ExternalReference,
+ ExternalReferenceType,
+ Property,
+ AttachedText,
+)
+from cyclonedx.model.bom import Bom
+from cyclonedx.model.component import Component, ComponentType
+from cyclonedx.model.contact import OrganizationalEntity, OrganizationalContact
+from cyclonedx.model.license import LicenseAcknowledgement, LicenseExpression
+from cyclonedx.model.lifecycle import PredefinedLifecycle, LifecyclePhase
+from cyclonedx.output.json import JsonV1Dot6
+from cyclonedx.schema import SchemaVersion
+from cyclonedx.validation.json import JsonStrictValidator
+
+if TYPE_CHECKING:
+ from cyclonedx.output.json import Json as JsonOutputter
+
+
+class TomlRequiredFieldError(Exception):
+ pass
+
+
+class MissingTomlFileError(Exception):
+ pass
+
+
+class SBOMWriteFailedError(Exception):
+ pass
+
+
+class ValidationFailedError(Exception):
+ pass
+
+
+class ValidationDependencyMissingError(Exception):
+ pass
+
+
+# TypedDict definitions for TOML data structures
+class CyclonePropertyDict(TypedDict):
+ name: str
+ value: str
+
+
+class LicenseDict(TypedDict):
+ license_id: str
+ text: str
+
+
+class RootComponentDict(TypedDict):
+ name: str
+ spdx_id: str
+ # Optional fields (since TypedDict doesn't support NotRequired in Python 3.9)
+ # We'll use .get() to access these safely
+ version: str
+ description: str
+ download_location: str
+ build_date: str
+ supplier: str
+ supplier_url: str
+ serial_number_uuid: str
+
+
+class ComponentDict(TypedDict):
+ name: str
+ spdx_id: str
+ # Optional fields
+ version: str
+ component_type: str
+ copyright: str
+ external_bom_link: str
+ supplier: str
+ purl_list: list[str]
+ cpe_list: list[str]
+ properties: list[CyclonePropertyDict]
+ dependencies: list[str]
+
+
+class BuildToolDict(TypedDict):
+ # Optional fields
+ name: str
+ component_type: str
+ version: str
+ description: str
+
+
+class TomlDataDict(TypedDict):
+ root_component: RootComponentDict
+ # Optional fields
+ project_build_tools: list[BuildToolDict]
+ components: list[ComponentDict]
+ licenses: list[LicenseDict]
+
+
+# Type alias for licenses dictionary
+LicensesDict = dict[str, LicenseDict]
+
+
+def validate_required_field(
+ data: Union[dict[str, Any], TomlDataDict, ComponentDict, RootComponentDict],
+ field: str,
+ context: str,
+) -> Any:
+ """Validate that a required field exists in the data dictionary.
+
+ Args:
+ data: The dictionary to check
+ field: The required field name
+ context: Description of where this validation is happening (for error messages)
+
+ Returns:
+ The value of the required field
+
+ Raises:
+ TomlRequiredFieldError: If the required field is missing
+ """
+ if field not in data:
+ raise TomlRequiredFieldError(f"Missing required field '{field}' in {context}")
+ return data[field]
+
+
+def _parse_build_date(date_str: str) -> datetime:
+ """Parse build date string, handling Python 3.9+ compatibility for Z suffix."""
+ override_to_utc = False
+ if sys.version_info < (3, 11) and date_str.endswith("Z"):
+ # Remove the Z at the end to support Python 3.9+, because
+ # datetime.fromisoformat learned to parse the Z in 3.11 only.
+ # In that case we need to override the timezone to be UTC manually.
+ date_str = date_str[:-1]
+ override_to_utc = True
+
+ build_date = datetime.fromisoformat(date_str)
+ if override_to_utc:
+ build_date = build_date.replace(tzinfo=timezone.utc)
+ return build_date
+
+
+def assign_optional_field(
+ source_data: Union[
+ dict[str, Any], TomlDataDict, ComponentDict, RootComponentDict, BuildToolDict
+ ],
+ target_args: dict[str, Any],
+ source_field: str,
+ target_field: Optional[str] = None,
+ transform: Optional[Callable[[Any], Any]] = None,
+) -> None:
+ """Assign an optional field from source data to target args if it exists.
+
+ Args:
+ source_data: The source dictionary to read from
+ target_args: The target dictionary to write to
+ source_field: The field name in the source data
+ target_field: The field name in the target args (defaults to source_field if None)
+ transform: Optional function to transform the value before assignment
+ """
+ if target_field is None:
+ target_field = source_field
+
+ if value := source_data.get(source_field):
+ if transform:
+ value = transform(value)
+ # Only assign if the transformed value is not None
+ if value is not None:
+ target_args[target_field] = value
+
+
+def main() -> None:
+ parser = get_cli_parser()
+ args = get_cli_args(parser)
+
+ handle_verbose_logging(args.verbose)
+
+ try:
+ create_cyclone_dx_sbom(
+ args.input_path,
+ args.output_path,
+ args.validate_json,
+ args.validate_json_required,
+ )
+ except (
+ TomlRequiredFieldError,
+ MissingTomlFileError,
+ SBOMWriteFailedError,
+ ValidationFailedError,
+ ValidationDependencyMissingError,
+ ) as e:
+ log.error(str(e))
+ sys.exit(1)
+
+
+def get_cli_parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(
+ formatter_class=argparse.RawTextHelpFormatter,
+ description="""
+Generates a CycloneDX v1.6 SBOM using intermediate information from a toml file created by Qt's
+SBOM generator.
+
+Example usage:
+python qt_cyclonedx_generator.py --input-path /qt/qtbase.cdx.toml --output-path /qt/qtbase.cdx.json
+""",
+ )
+ parser.add_argument(
+ "-i",
+ "--input-path",
+ type=Path,
+ help="Path to the intermediate toml file.",
+ required=True,
+ )
+ parser.add_argument(
+ "-o",
+ "--output-path",
+ type=Path,
+ help="Path to the CycloneDX output file.",
+ required=True,
+ )
+ parser.add_argument(
+ "--validate-json",
+ action="store_true",
+ help="Validate the generated CycloneDX JSON output against the CycloneDX schema.",
+ )
+ parser.add_argument(
+ "--validate-json-required",
+ action="store_true",
+ help="Error out if validation dependencies are missing.",
+ )
+ parser.add_argument(
+ "--verbose",
+ action="store_true",
+ help="Enable verbose logging output.",
+ )
+
+ return parser
+
+
+def get_cli_args(parser: argparse.ArgumentParser) -> argparse.Namespace:
+ args = parser.parse_args(args=None if sys.argv[1:] else ["--help"])
+ return args
+
+
+def handle_verbose_logging(verbose: bool) -> None:
+ if verbose:
+ log.setLevel(logging.DEBUG)
+
+
+# Reads a toml file and generates a CycloneDX SBOM file.
+def create_cyclone_dx_sbom(
+ input_path: Path,
+ output_path: Path,
+ validate_json=False,
+ validate_json_required=False,
+) -> None:
+ if not input_path or not input_path.exists():
+ raise MissingTomlFileError(
+ f"Failed to read toml file. Input file '{input_path}' does not exist."
+ )
+
+ cydx_bom = get_cydx_bom()
+ toml_data = read_toml_file(input_path)
+ process_toml(toml_data, cydx_bom)
+ json = write_cydx_sbom(cydx_bom, output_path)
+ if validate_json:
+ validate_cydx_bom(json, validate_json_required)
+
+
+def read_toml_file(input_path: Path) -> TomlDataDict:
+ log.debug(f"Reading toml file from '{input_path}'")
+ with open(input_path, "rb") as f:
+ # Manually read and decode the file contents, because older
+ # tomli versions vendored in pip don't handle this properly.
+ buffer = f.read()
+ toml_str = buffer.decode()
+ return cast(TomlDataDict, cast(Any, tomllib).loads(toml_str))
+
+
+# Serializes the CycloneDX BOM to JSON and writes it to the output path.
+def write_cydx_sbom(cydx_bom: Bom, output_path: Path) -> str:
+ json_outputter: JsonOutputter = JsonV1Dot6(cydx_bom)
+ log.debug(f"Serializing CycloneDX BOM to JSON at '{output_path}'")
+ serialized_json = json_outputter.output_as_string(indent=2)
+
+ try:
+ with open(output_path, "w") as f:
+ f.write(serialized_json)
+ except (OSError, IOError) as e:
+ raise SBOMWriteFailedError(f"Failed to write SBOM to '{output_path}': {e}")
+
+ return serialized_json
+
+
+def validate_cydx_bom(serialized_json: str, validate_json_required: bool) -> None:
+ log.debug("Validating CycloneDX JSON output against schema v1.6")
+ json_validator = JsonStrictValidator(SchemaVersion.V1_6)
+ try:
+ validation_errors = json_validator.validate_str(serialized_json)
+ if validation_errors:
+ raise ValidationFailedError(f"JSON validation failed: {validation_errors}")
+ except MissingOptionalDependencyException as error:
+ missing_dep_message = (
+ f"JSON-validation was failed due to missing Python dependency: {error}"
+ )
+ if validate_json_required:
+ raise ValidationDependencyMissingError(missing_dep_message)
+ else:
+ log.warning(missing_dep_message)
+
+
+def get_cydx_bom() -> Bom:
+ bom = Bom()
+ return bom
+
+
+# Reads toml data created by Qt's SBOM generator and populates the CycloneDX BOM.
+# At minimum, expects a root component dict, and a list of components.
+def process_toml(toml_data: TomlDataDict, cydx_bom: Bom) -> None:
+ components: dict[str, Component] = {}
+
+ log.debug("Processing TOML data.")
+
+ root_component_object, main_supplier, project_spdx_id = handle_root_component(
+ cydx_bom, toml_data
+ )
+ components[project_spdx_id] = root_component_object
+
+ if "project_build_tools" in toml_data:
+ project_build_tools = toml_data["project_build_tools"]
+ handle_project_build_tools(cydx_bom, project_build_tools)
+
+ external_components_spdx_ids = set()
+ components_toml = []
+ license_factory = LicenseFactory()
+
+ # Create one component per CMake target (in spdx it would be a spdx package).
+ if "components" in toml_data:
+ components_toml = toml_data["components"]
+
+ components_len = len(components_toml)
+ log.debug(f"Processing {components_len} components from TOML data.")
+
+ licenses_dict: LicensesDict = {}
+ if "licenses" in toml_data:
+ licenses_toml = toml_data["licenses"]
+ for license_entry in licenses_toml:
+ license_id = license_entry["license_id"]
+ licenses_dict[license_id] = license_entry
+
+ for component_toml in components_toml:
+ process_component(
+ cydx_bom,
+ component_toml,
+ licenses_dict,
+ components,
+ external_components_spdx_ids,
+ main_supplier,
+ license_factory,
+ )
+
+ # Register dependencies for each component.
+ log.debug("Processing component dependencies.")
+ for component_toml in components_toml:
+ handle_component_dependencies(
+ cydx_bom,
+ component_toml,
+ components,
+ external_components_spdx_ids,
+ root_component_object,
+ )
+
+
+# Creates the root component of the BOM.
+# The CycloneDX root component is mapped to the Qt spdx project package e.g. qtbase.
+def handle_root_component(
+ cydx_bom: Bom, toml_data: TomlDataDict
+) -> tuple[Component, Optional[OrganizationalEntity], str]:
+ root_components_args: dict[str, Any] = {
+ "type": ComponentType.FRAMEWORK,
+ }
+
+ root_component = validate_required_field(toml_data, "root_component", "TOML data")
+ error_context = "root_component"
+ project_name = validate_required_field(root_component, "name", error_context)
+ root_components_args["name"] = project_name
+
+ project_spdx_id = validate_required_field(root_component, "spdx_id", error_context)
+ root_components_args["bom_ref"] = project_spdx_id
+
+ # Process optional fields
+ assign_optional_field(root_component, root_components_args, "version")
+ assign_optional_field(root_component, root_components_args, "description")
+
+ # Process optional fields with transformations
+ assign_optional_field(
+ root_component,
+ root_components_args,
+ source_field="download_location",
+ target_field="external_references",
+ transform=lambda url: [
+ ExternalReference(
+ type=ExternalReferenceType.DISTRIBUTION, # pyright: ignore [reportCallIssue]
+ url=XsUri(url), # pyright: ignore [reportCallIssue]
+ )
+ ],
+ )
+
+ if project_build_date_str := root_component.get("build_date"):
+ project_build_date = _parse_build_date(project_build_date_str)
+ cydx_bom.metadata.timestamp = project_build_date # pyright: ignore [reportAttributeAccessIssue]
+
+ if serial_number_uuid := root_component.get("serial_number_uuid"):
+ cydx_bom.serial_number = UUID(serial_number_uuid) # pyright: ignore [reportAttributeAccessIssue]
+
+ project_supplier = root_component.get("supplier")
+ project_supplier_url = root_component.get("supplier_url")
+
+ # TODO: This is currently not supplied by the build system API.
+ project_supplier_email = root_component.get("supplier_email")
+
+ main_supplier = create_organization_entity(project_supplier, project_supplier_url)
+ main_author = create_organization_contact(project_supplier, project_supplier_email)
+
+ if main_supplier:
+ cydx_bom.metadata.manufacturer = main_supplier # pyright: ignore [reportAttributeAccessIssue]
+ cydx_bom.metadata.supplier = main_supplier # pyright: ignore [reportAttributeAccessIssue]
+
+ # FOSSA complains if author is not set.
+ cydx_bom.metadata.authors = [main_author] # pyright: ignore [reportAttributeAccessIssue]
+
+ root_components_args["supplier"] = main_supplier
+ root_components_args["manufacturer"] = main_supplier
+
+ root_component_object = Component(**root_components_args)
+ cydx_bom.metadata.component = root_component_object # pyright: ignore [reportAttributeAccessIssue]
+
+ cydx_bom.metadata.lifecycles = [PredefinedLifecycle(phase=LifecyclePhase.BUILD)] # pyright: ignore [reportAttributeAccessIssue, reportCallIssue]
+
+ root_component_name_str = f"{root_component_object.name}" # pyright: ignore [reportAttributeAccessIssue]
+ root_component_version_str = f"(version {root_component_object.version})" # pyright: ignore [reportAttributeAccessIssue]
+ log.debug(
+ f"Created root component of the BOM. "
+ f"{root_component_name_str} ${root_component_version_str}"
+ )
+
+ return root_component_object, main_supplier, project_spdx_id
+
+
+# Handles project build tools and adds them as components to the BOM metadata tools section.
+# This is for tools like CMake, Ninja, etc.
+# Unclear yet if compilers and linkers should also go here.
+def handle_project_build_tools(
+ cydx_bom: Bom, project_build_tools_toml: list[BuildToolDict]
+) -> None:
+ log.debug("Processing project build tools.")
+
+ for build_tool_toml in project_build_tools_toml:
+ component_args = {}
+
+ assign_optional_field(build_tool_toml, component_args, source_field="name")
+ assign_optional_field(
+ build_tool_toml,
+ component_args,
+ source_field="component_type",
+ target_field="type",
+ transform=get_component_type_for_str,
+ )
+ assign_optional_field(build_tool_toml, component_args, "version")
+ assign_optional_field(build_tool_toml, component_args, "description")
+
+ component = Component(**component_args)
+ log.debug(
+ f"Created build tool component '{component.name} (version {component.version})'." # pyright: ignore [reportAttributeAccessIssue]
+ )
+ cydx_bom.metadata.tools.components.add(component) # pyright: ignore [reportAttributeAccessIssue]
+
+
+# Creates a CycloneDX component from the toml component data and adds it to the BOM.
+# The SPDX equivalent would be a SPDX package backed by a CMake target.
+# We mostly reuse spdx ids as bom-refs, rather than generating new ones. Makes it
+# easier to cross-check with the original SPDX data. And it's not like CycloneDX forbids it.
+def process_component(
+ cydx_bom: Bom,
+ component_toml: ComponentDict,
+ licenses_dict: LicensesDict,
+ components: dict[str, Component],
+ external_components_spdx_ids: set[str],
+ main_supplier: Optional[OrganizationalEntity],
+ license_factory: LicenseFactory,
+) -> None:
+ component_args = {}
+ properties = []
+
+ error_context = "component"
+ component_name = validate_required_field(component_toml, "name", error_context)
+ component_args["name"] = component_name
+
+ assign_optional_field(
+ component_toml,
+ component_args,
+ "version",
+ transform=lambda v: v if v != "unknown" else None,
+ )
+
+ # A spdx id maps to a bom-ref in CycloneDX.
+ spdx_id = validate_required_field(component_toml, "spdx_id", error_context)
+ component_args["bom_ref"] = spdx_id
+
+ # Some components might be external to the current BOM.
+ # For example for the QtSvg module, QtCore is external, because it's built in qtbase,
+ # not qtsvg. To be able to declare a dependency on QtCore, we still need to add it as a
+ # component. But we add a BOM external reference link to it, signalling that the full
+ # component information is in a different BOM.
+ assign_optional_field(
+ component_toml,
+ component_args,
+ source_field="external_bom_link",
+ target_field="external_references",
+ transform=lambda link: [
+ ExternalReference(
+ type=ExternalReferenceType.BOM, # pyright: ignore [reportCallIssue]
+ url=XsUri(link), # pyright: ignore [reportCallIssue]
+ )
+ ],
+ )
+ if component_toml.get("external_bom_link"):
+ external_components_spdx_ids.add(spdx_id)
+
+ assign_optional_field(
+ component_toml,
+ component_args,
+ source_field="component_type",
+ target_field="type",
+ transform=get_component_type_for_str,
+ )
+
+ assign_optional_field(
+ component_toml,
+ component_args,
+ source_field="copyright",
+ target_field="copyright",
+ )
+
+ handle_component_licenses(
+ component_toml, licenses_dict, license_factory, component_args
+ )
+
+ purl_list = component_toml.get("purl_list", [])
+ cpe_list = component_toml.get("cpe_list", [])
+ cpe_purl_args, extra_cpe_purl_properties = get_purl_and_cpe_component_args(
+ purl_list, cpe_list
+ )
+ if extra_cpe_purl_properties:
+ properties.extend(extra_cpe_purl_properties)
+
+ if supplier_name := component_toml.get("supplier"):
+ # If the specified supplier is the same as the main supplier, reuse it, because it has a
+ # url.
+ if main_supplier and supplier_name == main_supplier.name: # pyright: ignore [reportAttributeAccessIssue]
+ component_args["supplier"] = main_supplier
+ else:
+ component_supplier = create_organization_entity(supplier_name)
+ component_args["supplier"] = component_supplier
+
+ # Properties are extra vendor-specific information that are not part of the official spec.
+ if properties_list := component_toml.get("properties"):
+ for prop in properties_list:
+ properties.append(
+ Property(
+ name=prop["name"], # pyright: ignore [reportCallIssue]
+ value=prop["value"], # pyright: ignore [reportCallIssue]
+ )
+ )
+ if properties:
+ component_args["properties"] = properties
+
+ component = Component(**component_args, **cpe_purl_args)
+
+ log.debug(f"Created component '{component.name} (version {component.version})'.") # pyright: ignore [reportAttributeAccessIssue]
+
+ cydx_bom.components.add(component) # pyright: ignore [reportAttributeAccessIssue]
+ components[spdx_id] = component
+
+
+# Creates dependencies between components in the BOM, as well as between the root component
+# and non-external components that are part of the current BOM.
+def handle_component_dependencies(
+ cydx_bom: Bom,
+ component_toml: ComponentDict,
+ components: dict[str, Component],
+ external_components_spdx_ids: set[str],
+ root_component_object: Component,
+) -> None:
+ component_id = component_toml["spdx_id"]
+ component_object = components.get(component_id)
+
+ # If the component is not external, register it as a dependency of the root component,
+ # aka the root component "contains" the non-external component.
+ if component_id not in external_components_spdx_ids:
+ cydx_bom.register_dependency(root_component_object, [component_object]) # pyright: ignore [reportAttributeAccessIssue, reportArgumentType]
+
+ # Register dependencies declared in the toml.
+ # CycloneDX does not support different dependency types, like SPDX does.
+ if dependencies := component_toml.get("dependencies"):
+ for dependency_spdx_id in dependencies:
+ if dependency_spdx_id not in components:
+ log.warning(
+ f"Component {component_id} has a dependency on unknown component {dependency_spdx_id}, skipping."
+ )
+ continue
+ dep_component = components[dependency_spdx_id]
+ cydx_bom.register_dependency(component_object, [dep_component]) # pyright: ignore [reportAttributeAccessIssue, reportArgumentType]
+ log.debug(
+ f"Created dependency from '{component_id}' to '{dependency_spdx_id}'."
+ )
+
+
+# Handles PURL and CPE entries for a component.
+# The spec says that a component can have exactly one PURL. Qt generates several, because it's
+# unclear what will end up being useful for tooling. The other PURLs are added as extra
+# component properties. Same for CPEs.
+# The field names were picked to match the names generated by the python spdx to cyclonedx converter.
+def get_purl_and_cpe_component_args(
+ purl_list: list[str],
+ cpe_list: list[str],
+) -> tuple[dict[str, Any], list[Property]]:
+ component_args = {}
+ properties = []
+
+ purl_objects = [PackageURL.from_string(purl) for purl in purl_list if purl]
+
+ if len(purl_objects) > 0:
+ # First PURL will be the main one.
+ purl = purl_objects.pop(0)
+ component_args["purl"] = purl
+
+ # Rest will be properties.
+ for purl_entry in purl_objects:
+ properties.append(
+ Property(
+ name="spdx:external-reference:package-manager:purl", # pyright: ignore [reportCallIssue]
+ value=str(purl_entry), # pyright: ignore [reportCallIssue]
+ )
+ )
+
+ if len(cpe_list) > 0:
+ # First CPE will be the main one.
+ cpe = cpe_list.pop(0)
+ component_args["cpe"] = cpe
+
+ # Rest will be properties.
+ for cpe_entry in cpe_list:
+ properties.append(
+ Property(
+ name="spdx:external-reference:security:cpe23", # pyright: ignore [reportCallIssue]
+ value=str(cpe_entry), # pyright: ignore [reportCallIssue]
+ )
+ )
+
+ return component_args, properties
+
+
+# Handles licenses for a component.
+def handle_component_licenses(
+ component_toml: ComponentDict,
+ licenses_dict: LicensesDict,
+ license_factory: LicenseFactory,
+ component_args: dict[str, Any],
+) -> None:
+ def transformer(license_expression: str) -> Optional[list[LicenseExpression]]:
+ acknowledgement = LicenseAcknowledgement.CONCLUDED
+ return convert_license_expression_license_objects(
+ license_expression, licenses_dict, license_factory, acknowledgement
+ )
+
+ assign_optional_field(
+ component_toml,
+ component_args,
+ source_field="license_concluded_expression",
+ target_field="licenses",
+ transform=transformer,
+ )
+
+
+# Transforms a spdx license expression into CycloneDX license objects.
+def convert_license_expression_license_objects(
+ license_expression: str,
+ licenses_dict: LicensesDict,
+ license_factory: LicenseFactory,
+ acknowledgement: LicenseAcknowledgement,
+) -> Optional[list[LicenseExpression]]:
+ if "LicenseRef-" in license_expression:
+ return handle_custom_license_ref_expression(
+ license_expression, licenses_dict, license_factory, acknowledgement
+ )
+ else:
+ return handle_standard_license_ref_expression(
+ license_expression, license_factory, acknowledgement
+ )
+
+
+# CycloneDX v1.6 doesn't support an expression that contains LicenseRef- in it.
+# CycloneDX v1.7 seemingly does.
+# https://github.com/CycloneDX/specification/issues/454
+# https://github.com/CycloneDX/specification/issues/554
+# https://github.com/CycloneDX/specification/pull/582
+#
+# Split LicenseRef-* expressions into separate licenses, by which we lose the expression structure,
+# but at least preserve the license information.
+#
+# TODO: Improve this when CycloneDX v1.7 generation is added.
+def handle_custom_license_ref_expression(
+ license_expression: str,
+ licenses_dict: LicensesDict,
+ license_factory: LicenseFactory,
+ acknowledgement: LicenseAcknowledgement,
+) -> list[LicenseExpression]:
+ license_objects = []
+ licensing = get_spdx_licensing()
+ symbols = licensing.license_symbols(license_expression)
+
+ for symbol in symbols:
+ license_text = None
+ # This can be either a known public spdx id, in which case we won't have text for.
+ # Or it can be a LicenseRef-* for which we have license text in the licenses_dict.
+ maybe_license_id = symbol.key # pyright: ignore [reportAttributeAccessIssue]
+
+ if maybe_license_id in licenses_dict:
+ # Get the text for the LicenseRef-* entry.
+ maybe_license_text = licenses_dict[maybe_license_id].get("text")
+ license_text = AttachedText(content=maybe_license_text) # pyright: ignore [reportCallIssue]
+
+ license_obj = license_factory.make_from_string(
+ maybe_license_id,
+ license_text=license_text,
+ license_acknowledgement=acknowledgement,
+ )
+ license_objects.append(license_obj)
+
+ return license_objects
+
+
+# Transforms a spdx license expression without LicenseRef-* into a CycloneDX license object.
+def handle_standard_license_ref_expression(
+ license_expression: str,
+ license_factory: LicenseFactory,
+ acknowledgement: LicenseAcknowledgement,
+) -> list[LicenseExpression]:
+ license_obj = license_factory.make_with_expression(
+ expression=license_expression, acknowledgement=acknowledgement
+ )
+ return [license_obj]
+
+
+# Transform from enum string value to actual enum.
+def get_component_type_for_str(component_type_str: str) -> ComponentType:
+ return ComponentType(component_type_str)
+
+
+# Creates an OrganizationalEntity for a supplier/manufacturer.
+def create_organization_entity(
+ supplier_name: Optional[str] = None, supplier_url: Optional[str] = None
+) -> Optional[OrganizationalEntity]:
+ args = {}
+ if supplier_name:
+ args["name"] = supplier_name
+ if supplier_url:
+ args["urls"] = [XsUri(supplier_url)] # pyright: ignore [reportCallIssue]
+
+ # Check if args has at least one entry.
+ if len(args) > 0:
+ return OrganizationalEntity(**args)
+
+ return None
+
+
+# Creates an OrganizationalContact for a supplier/manufacturer.
+def create_organization_contact(
+ contact_name: Optional[str] = None, contact_email: Optional[str] = None
+) -> Optional[OrganizationalContact]:
+ args = {}
+ if contact_name:
+ args["name"] = contact_name
+ if contact_email:
+ args["email"] = contact_email # pyright: ignore [reportCallIssue]
+
+ # Check if args has at least one entry.
+ if len(args) > 0:
+ return OrganizationalContact(**args)
+
+ return None
+
+
+if __name__ == "__main__":
+ main()
diff --git a/util/sbom/cyclonedx/uv.lock b/util/sbom/cyclonedx/uv.lock
new file mode 100644
index 00000000000..0b16a99e481
--- /dev/null
+++ b/util/sbom/cyclonedx/uv.lock
@@ -0,0 +1,625 @@
+version = 1
+revision = 3
+requires-python = ">=3.9"
+resolution-markers = [
+ "python_full_version >= '3.10'",
+ "python_full_version < '3.10'",
+]
+
+[[package]]
+name = "arrow"
+version = "1.4.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "python-dateutil" },
+ { name = "tzdata" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931, upload-time = "2025-10-18T17:46:46.761Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" },
+]
+
+[[package]]
+name = "attrs"
+version = "25.4.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" },
+]
+
+[[package]]
+name = "boolean-py"
+version = "5.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/c4/cf/85379f13b76f3a69bca86b60237978af17d6aa0bc5998978c3b8cf05abb2/boolean_py-5.0.tar.gz", hash = "sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95", size = 37047, upload-time = "2025-04-03T10:39:49.734Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl", hash = "sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9", size = 26577, upload-time = "2025-04-03T10:39:48.449Z" },
+]
+
+[[package]]
+name = "cyclonedx-python-lib"
+version = "11.3.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "license-expression" },
+ { name = "packageurl-python" },
+ { name = "py-serializable" },
+ { name = "sortedcontainers" },
+ { name = "typing-extensions", marker = "python_full_version < '3.13'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/23/3b/c130406ae35bd264be7f816afbb01f95ccc4a63a5eeadfea5249d110efb2/cyclonedx_python_lib-11.3.0.tar.gz", hash = "sha256:ee3135a59ead90397339ea585b341a7ea9c53e734ad13f48a9865cfcf0f1139a", size = 1046415, upload-time = "2025-10-22T11:03:04.883Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/32/28/3bebcfe7f87e485164fba1dca08b6307bdbee6cc45d6bf57343552346f85/cyclonedx_python_lib-11.3.0-py3-none-any.whl", hash = "sha256:08094495d0cbbaddbe605f60f6e48ae98d29263386d7926df83ffe9bdea55f78", size = 383140, upload-time = "2025-10-22T11:03:03.102Z" },
+]
+
+[package.optional-dependencies]
+json-validation = [
+ { name = "jsonschema", extra = ["format-nongpl"] },
+ { name = "referencing", version = "0.36.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
+ { name = "referencing", version = "0.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+]
+
+[[package]]
+name = "defusedxml"
+version = "0.7.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" },
+]
+
+[[package]]
+name = "fqdn"
+version = "1.5.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" },
+]
+
+[[package]]
+name = "idna"
+version = "3.11"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" },
+]
+
+[[package]]
+name = "isoduration"
+version = "20.11.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "arrow" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" },
+]
+
+[[package]]
+name = "jsonpointer"
+version = "3.0.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" },
+]
+
+[[package]]
+name = "jsonschema"
+version = "4.25.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "attrs" },
+ { name = "jsonschema-specifications" },
+ { name = "referencing", version = "0.36.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
+ { name = "referencing", version = "0.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+ { name = "rpds-py" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/74/69/f7185de793a29082a9f3c7728268ffb31cb5095131a9c139a74078e27336/jsonschema-4.25.1.tar.gz", hash = "sha256:e4a9655ce0da0c0b67a085847e00a3a51449e1157f4f75e9fb5aa545e122eb85", size = 357342, upload-time = "2025-08-18T17:03:50.038Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/bf/9c/8c95d856233c1f82500c2450b8c68576b4cf1c871db3afac5c34ff84e6fd/jsonschema-4.25.1-py3-none-any.whl", hash = "sha256:3fba0169e345c7175110351d456342c364814cfcf3b964ba4587f22915230a63", size = 90040, upload-time = "2025-08-18T17:03:48.373Z" },
+]
+
+[package.optional-dependencies]
+format-nongpl = [
+ { name = "fqdn" },
+ { name = "idna" },
+ { name = "isoduration" },
+ { name = "jsonpointer" },
+ { name = "rfc3339-validator" },
+ { name = "rfc3986-validator" },
+ { name = "rfc3987-syntax" },
+ { name = "uri-template" },
+ { name = "webcolors" },
+]
+
+[[package]]
+name = "jsonschema-specifications"
+version = "2025.9.1"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "referencing", version = "0.36.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
+ { name = "referencing", version = "0.37.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" },
+]
+
+[[package]]
+name = "lark"
+version = "1.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/1d/37/a13baf0135f348af608c667633cbe5d13aa2c5c15a56ae9ad3e6cba45ae3/lark-1.3.0.tar.gz", hash = "sha256:9a3839d0ca5e1faf7cfa3460e420e859b66bcbde05b634e73c369c8244c5fa48", size = 259551, upload-time = "2025-09-22T13:45:05.072Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a8/3e/1c6b43277de64fc3c0333b0e72ab7b52ddaaea205210d60d9b9f83c3d0c7/lark-1.3.0-py3-none-any.whl", hash = "sha256:80661f261fb2584a9828a097a2432efd575af27d20be0fd35d17f0fe37253831", size = 113002, upload-time = "2025-09-22T13:45:03.747Z" },
+]
+
+[[package]]
+name = "license-expression"
+version = "30.4.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "boolean-py" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/40/71/d89bb0e71b1415453980fd32315f2a037aad9f7f70f695c7cec7035feb13/license_expression-30.4.4.tar.gz", hash = "sha256:73448f0aacd8d0808895bdc4b2c8e01a8d67646e4188f887375398c761f340fd", size = 186402, upload-time = "2025-07-22T11:13:32.17Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl", hash = "sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4", size = 120615, upload-time = "2025-07-22T11:13:31.217Z" },
+]
+
+[[package]]
+name = "nodeenv"
+version = "1.9.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" },
+]
+
+[[package]]
+name = "packageurl-python"
+version = "0.17.5"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/3a/f0/de0ac00a4484c0d87b71e3d9985518278d89797fa725e90abd3453bccb42/packageurl_python-0.17.5.tar.gz", hash = "sha256:a7be3f3ba70d705f738ace9bf6124f31920245a49fa69d4b416da7037dd2de61", size = 43832, upload-time = "2025-08-06T14:08:20.235Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/be/78/9dbb7d2ef240d20caf6f79c0f66866737c9d0959601fd783ff635d1d019d/packageurl_python-0.17.5-py3-none-any.whl", hash = "sha256:f0e55452ab37b5c192c443de1458e3f3b4d8ac27f747df6e8c48adeab081d321", size = 30544, upload-time = "2025-08-06T14:08:19.055Z" },
+]
+
+[[package]]
+name = "py-serializable"
+version = "2.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "defusedxml" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/73/21/d250cfca8ff30c2e5a7447bc13861541126ce9bd4426cd5d0c9f08b5547d/py_serializable-2.1.0.tar.gz", hash = "sha256:9d5db56154a867a9b897c0163b33a793c804c80cee984116d02d49e4578fc103", size = 52368, upload-time = "2025-07-21T09:56:48.07Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9b/bf/7595e817906a29453ba4d99394e781b6fabe55d21f3c15d240f85dd06bb1/py_serializable-2.1.0-py3-none-any.whl", hash = "sha256:b56d5d686b5a03ba4f4db5e769dc32336e142fc3bd4d68a8c25579ebb0a67304", size = 23045, upload-time = "2025-07-21T09:56:46.848Z" },
+]
+
+[[package]]
+name = "pyright"
+version = "1.1.406"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "nodeenv" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/f7/16/6b4fbdd1fef59a0292cbb99f790b44983e390321eccbc5921b4d161da5d1/pyright-1.1.406.tar.gz", hash = "sha256:c4872bc58c9643dac09e8a2e74d472c62036910b3bd37a32813989ef7576ea2c", size = 4113151, upload-time = "2025-10-02T01:04:45.488Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f6/a2/e309afbb459f50507103793aaef85ca4348b66814c86bc73908bdeb66d12/pyright-1.1.406-py3-none-any.whl", hash = "sha256:1d81fb43c2407bf566e97e57abb01c811973fdb21b2df8df59f870f688bdca71", size = 5980982, upload-time = "2025-10-02T01:04:43.137Z" },
+]
+
+[[package]]
+name = "python-dateutil"
+version = "2.9.0.post0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
+]
+
+[[package]]
+name = "qt-cyclonedx-generator"
+version = "0.1.0"
+source = { editable = "." }
+dependencies = [
+ { name = "cyclonedx-python-lib", extra = ["json-validation"] },
+ { name = "tomli", marker = "python_full_version < '3.11'" },
+]
+
+[package.dev-dependencies]
+dev = [
+ { name = "pyright" },
+ { name = "ruff" },
+ { name = "setuptools" },
+ { name = "tomli" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "cyclonedx-python-lib", extras = ["json-validation"], specifier = ">=10.0.0" },
+ { name = "tomli", marker = "python_full_version < '3.11'" },
+]
+
+[package.metadata.requires-dev]
+dev = [
+ { name = "pyright", specifier = ">=1.1.406" },
+ { name = "ruff", specifier = ">=0.11.2" },
+ { name = "setuptools", specifier = ">=65" },
+ { name = "tomli", specifier = ">=2.3.0" },
+]
+
+[[package]]
+name = "referencing"
+version = "0.36.2"
+source = { registry = "https://pypi.org/simple" }
+resolution-markers = [
+ "python_full_version < '3.10'",
+]
+dependencies = [
+ { name = "attrs", marker = "python_full_version < '3.10'" },
+ { name = "rpds-py", marker = "python_full_version < '3.10'" },
+ { name = "typing-extensions", marker = "python_full_version < '3.10'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744, upload-time = "2025-01-25T08:48:16.138Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775, upload-time = "2025-01-25T08:48:14.241Z" },
+]
+
+[[package]]
+name = "referencing"
+version = "0.37.0"
+source = { registry = "https://pypi.org/simple" }
+resolution-markers = [
+ "python_full_version >= '3.10'",
+]
+dependencies = [
+ { name = "attrs", marker = "python_full_version >= '3.10'" },
+ { name = "rpds-py", marker = "python_full_version >= '3.10'" },
+ { name = "typing-extensions", marker = "python_full_version >= '3.10' and python_full_version < '3.13'" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" },
+]
+
+[[package]]
+name = "rfc3339-validator"
+version = "0.1.4"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "six" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" },
+]
+
+[[package]]
+name = "rfc3986-validator"
+version = "0.1.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" },
+]
+
+[[package]]
+name = "rfc3987-syntax"
+version = "1.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "lark" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" },
+]
+
+[[package]]
+name = "rpds-py"
+version = "0.27.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e9/dd/2c0cbe774744272b0ae725f44032c77bdcab6e8bcf544bffa3b6e70c8dba/rpds_py-0.27.1.tar.gz", hash = "sha256:26a1c73171d10b7acccbded82bf6a586ab8203601e565badc74bbbf8bc5a10f8", size = 27479, upload-time = "2025-08-27T12:16:36.024Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a5/ed/3aef893e2dd30e77e35d20d4ddb45ca459db59cead748cad9796ad479411/rpds_py-0.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:68afeec26d42ab3b47e541b272166a0b4400313946871cba3ed3a4fc0cab1cef", size = 371606, upload-time = "2025-08-27T12:12:25.189Z" },
+ { url = "https://files.pythonhosted.org/packages/6d/82/9818b443e5d3eb4c83c3994561387f116aae9833b35c484474769c4a8faf/rpds_py-0.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74e5b2f7bb6fa38b1b10546d27acbacf2a022a8b5543efb06cfebc72a59c85be", size = 353452, upload-time = "2025-08-27T12:12:27.433Z" },
+ { url = "https://files.pythonhosted.org/packages/99/c7/d2a110ffaaa397fc6793a83c7bd3545d9ab22658b7cdff05a24a4535cc45/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9024de74731df54546fab0bfbcdb49fae19159ecaecfc8f37c18d2c7e2c0bd61", size = 381519, upload-time = "2025-08-27T12:12:28.719Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/bc/e89581d1f9d1be7d0247eaef602566869fdc0d084008ba139e27e775366c/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:31d3ebadefcd73b73928ed0b2fd696f7fefda8629229f81929ac9c1854d0cffb", size = 394424, upload-time = "2025-08-27T12:12:30.207Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/2e/36a6861f797530e74bb6ed53495f8741f1ef95939eed01d761e73d559067/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2e7f8f169d775dd9092a1743768d771f1d1300453ddfe6325ae3ab5332b4657", size = 523467, upload-time = "2025-08-27T12:12:31.808Z" },
+ { url = "https://files.pythonhosted.org/packages/c4/59/c1bc2be32564fa499f988f0a5c6505c2f4746ef96e58e4d7de5cf923d77e/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d905d16f77eb6ab2e324e09bfa277b4c8e5e6b8a78a3e7ff8f3cdf773b4c013", size = 402660, upload-time = "2025-08-27T12:12:33.444Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/ec/ef8bf895f0628dd0a59e54d81caed6891663cb9c54a0f4bb7da918cb88cf/rpds_py-0.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50c946f048209e6362e22576baea09193809f87687a95a8db24e5fbdb307b93a", size = 384062, upload-time = "2025-08-27T12:12:34.857Z" },
+ { url = "https://files.pythonhosted.org/packages/69/f7/f47ff154be8d9a5e691c083a920bba89cef88d5247c241c10b9898f595a1/rpds_py-0.27.1-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:3deab27804d65cd8289eb814c2c0e807c4b9d9916c9225e363cb0cf875eb67c1", size = 401289, upload-time = "2025-08-27T12:12:36.085Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/d9/ca410363efd0615814ae579f6829cafb39225cd63e5ea5ed1404cb345293/rpds_py-0.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8b61097f7488de4be8244c89915da8ed212832ccf1e7c7753a25a394bf9b1f10", size = 417718, upload-time = "2025-08-27T12:12:37.401Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/a0/8cb5c2ff38340f221cc067cc093d1270e10658ba4e8d263df923daa18e86/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8a3f29aba6e2d7d90528d3c792555a93497fe6538aa65eb675b44505be747808", size = 558333, upload-time = "2025-08-27T12:12:38.672Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/8c/1b0de79177c5d5103843774ce12b84caa7164dfc6cd66378768d37db11bf/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dd6cd0485b7d347304067153a6dc1d73f7d4fd995a396ef32a24d24b8ac63ac8", size = 589127, upload-time = "2025-08-27T12:12:41.48Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/5e/26abb098d5e01266b0f3a2488d299d19ccc26849735d9d2b95c39397e945/rpds_py-0.27.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6f4461bf931108c9fa226ffb0e257c1b18dc2d44cd72b125bec50ee0ab1248a9", size = 554899, upload-time = "2025-08-27T12:12:42.925Z" },
+ { url = "https://files.pythonhosted.org/packages/de/41/905cc90ced13550db017f8f20c6d8e8470066c5738ba480d7ba63e3d136b/rpds_py-0.27.1-cp310-cp310-win32.whl", hash = "sha256:ee5422d7fb21f6a00c1901bf6559c49fee13a5159d0288320737bbf6585bd3e4", size = 217450, upload-time = "2025-08-27T12:12:44.813Z" },
+ { url = "https://files.pythonhosted.org/packages/75/3d/6bef47b0e253616ccdf67c283e25f2d16e18ccddd38f92af81d5a3420206/rpds_py-0.27.1-cp310-cp310-win_amd64.whl", hash = "sha256:3e039aabf6d5f83c745d5f9a0a381d031e9ed871967c0a5c38d201aca41f3ba1", size = 228447, upload-time = "2025-08-27T12:12:46.204Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/c1/7907329fbef97cbd49db6f7303893bd1dd5a4a3eae415839ffdfb0762cae/rpds_py-0.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:be898f271f851f68b318872ce6ebebbc62f303b654e43bf72683dbdc25b7c881", size = 371063, upload-time = "2025-08-27T12:12:47.856Z" },
+ { url = "https://files.pythonhosted.org/packages/11/94/2aab4bc86228bcf7c48760990273653a4900de89c7537ffe1b0d6097ed39/rpds_py-0.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:62ac3d4e3e07b58ee0ddecd71d6ce3b1637de2d373501412df395a0ec5f9beb5", size = 353210, upload-time = "2025-08-27T12:12:49.187Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/57/f5eb3ecf434342f4f1a46009530e93fd201a0b5b83379034ebdb1d7c1a58/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4708c5c0ceb2d034f9991623631d3d23cb16e65c83736ea020cdbe28d57c0a0e", size = 381636, upload-time = "2025-08-27T12:12:50.492Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/f4/ef95c5945e2ceb5119571b184dd5a1cc4b8541bbdf67461998cfeac9cb1e/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:abfa1171a9952d2e0002aba2ad3780820b00cc3d9c98c6630f2e93271501f66c", size = 394341, upload-time = "2025-08-27T12:12:52.024Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/7e/4bd610754bf492d398b61725eb9598ddd5eb86b07d7d9483dbcd810e20bc/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b507d19f817ebaca79574b16eb2ae412e5c0835542c93fe9983f1e432aca195", size = 523428, upload-time = "2025-08-27T12:12:53.779Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/e5/059b9f65a8c9149361a8b75094864ab83b94718344db511fd6117936ed2a/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:168b025f8fd8d8d10957405f3fdcef3dc20f5982d398f90851f4abc58c566c52", size = 402923, upload-time = "2025-08-27T12:12:55.15Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/48/64cabb7daced2968dd08e8a1b7988bf358d7bd5bcd5dc89a652f4668543c/rpds_py-0.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb56c6210ef77caa58e16e8c17d35c63fe3f5b60fd9ba9d424470c3400bcf9ed", size = 384094, upload-time = "2025-08-27T12:12:57.194Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/e1/dc9094d6ff566bff87add8a510c89b9e158ad2ecd97ee26e677da29a9e1b/rpds_py-0.27.1-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:d252f2d8ca0195faa707f8eb9368955760880b2b42a8ee16d382bf5dd807f89a", size = 401093, upload-time = "2025-08-27T12:12:58.985Z" },
+ { url = "https://files.pythonhosted.org/packages/37/8e/ac8577e3ecdd5593e283d46907d7011618994e1d7ab992711ae0f78b9937/rpds_py-0.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6e5e54da1e74b91dbc7996b56640f79b195d5925c2b78efaa8c5d53e1d88edde", size = 417969, upload-time = "2025-08-27T12:13:00.367Z" },
+ { url = "https://files.pythonhosted.org/packages/66/6d/87507430a8f74a93556fe55c6485ba9c259949a853ce407b1e23fea5ba31/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ffce0481cc6e95e5b3f0a47ee17ffbd234399e6d532f394c8dce320c3b089c21", size = 558302, upload-time = "2025-08-27T12:13:01.737Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/bb/1db4781ce1dda3eecc735e3152659a27b90a02ca62bfeea17aee45cc0fbc/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a205fdfe55c90c2cd8e540ca9ceba65cbe6629b443bc05db1f590a3db8189ff9", size = 589259, upload-time = "2025-08-27T12:13:03.127Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/0e/ae1c8943d11a814d01b482e1f8da903f88047a962dff9bbdadf3bd6e6fd1/rpds_py-0.27.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:689fb5200a749db0415b092972e8eba85847c23885c8543a8b0f5c009b1a5948", size = 554983, upload-time = "2025-08-27T12:13:04.516Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/d5/0b2a55415931db4f112bdab072443ff76131b5ac4f4dc98d10d2d357eb03/rpds_py-0.27.1-cp311-cp311-win32.whl", hash = "sha256:3182af66048c00a075010bc7f4860f33913528a4b6fc09094a6e7598e462fe39", size = 217154, upload-time = "2025-08-27T12:13:06.278Z" },
+ { url = "https://files.pythonhosted.org/packages/24/75/3b7ffe0d50dc86a6a964af0d1cc3a4a2cdf437cb7b099a4747bbb96d1819/rpds_py-0.27.1-cp311-cp311-win_amd64.whl", hash = "sha256:b4938466c6b257b2f5c4ff98acd8128ec36b5059e5c8f8372d79316b1c36bb15", size = 228627, upload-time = "2025-08-27T12:13:07.625Z" },
+ { url = "https://files.pythonhosted.org/packages/8d/3f/4fd04c32abc02c710f09a72a30c9a55ea3cc154ef8099078fd50a0596f8e/rpds_py-0.27.1-cp311-cp311-win_arm64.whl", hash = "sha256:2f57af9b4d0793e53266ee4325535a31ba48e2f875da81a9177c9926dfa60746", size = 220998, upload-time = "2025-08-27T12:13:08.972Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/fe/38de28dee5df58b8198c743fe2bea0c785c6d40941b9950bac4cdb71a014/rpds_py-0.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ae2775c1973e3c30316892737b91f9283f9908e3cc7625b9331271eaaed7dc90", size = 361887, upload-time = "2025-08-27T12:13:10.233Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/9a/4b6c7eedc7dd90986bf0fab6ea2a091ec11c01b15f8ba0a14d3f80450468/rpds_py-0.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2643400120f55c8a96f7c9d858f7be0c88d383cd4653ae2cf0d0c88f668073e5", size = 345795, upload-time = "2025-08-27T12:13:11.65Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/0e/e650e1b81922847a09cca820237b0edee69416a01268b7754d506ade11ad/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16323f674c089b0360674a4abd28d5042947d54ba620f72514d69be4ff64845e", size = 385121, upload-time = "2025-08-27T12:13:13.008Z" },
+ { url = "https://files.pythonhosted.org/packages/1b/ea/b306067a712988e2bff00dcc7c8f31d26c29b6d5931b461aa4b60a013e33/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a1f4814b65eacac94a00fc9a526e3fdafd78e439469644032032d0d63de4881", size = 398976, upload-time = "2025-08-27T12:13:14.368Z" },
+ { url = "https://files.pythonhosted.org/packages/2c/0a/26dc43c8840cb8fe239fe12dbc8d8de40f2365e838f3d395835dde72f0e5/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ba32c16b064267b22f1850a34051121d423b6f7338a12b9459550eb2096e7ec", size = 525953, upload-time = "2025-08-27T12:13:15.774Z" },
+ { url = "https://files.pythonhosted.org/packages/22/14/c85e8127b573aaf3a0cbd7fbb8c9c99e735a4a02180c84da2a463b766e9e/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5c20f33fd10485b80f65e800bbe5f6785af510b9f4056c5a3c612ebc83ba6cb", size = 407915, upload-time = "2025-08-27T12:13:17.379Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/7b/8f4fee9ba1fb5ec856eb22d725a4efa3deb47f769597c809e03578b0f9d9/rpds_py-0.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:466bfe65bd932da36ff279ddd92de56b042f2266d752719beb97b08526268ec5", size = 386883, upload-time = "2025-08-27T12:13:18.704Z" },
+ { url = "https://files.pythonhosted.org/packages/86/47/28fa6d60f8b74fcdceba81b272f8d9836ac0340570f68f5df6b41838547b/rpds_py-0.27.1-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:41e532bbdcb57c92ba3be62c42e9f096431b4cf478da9bc3bc6ce5c38ab7ba7a", size = 405699, upload-time = "2025-08-27T12:13:20.089Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/fd/c5987b5e054548df56953a21fe2ebed51fc1ec7c8f24fd41c067b68c4a0a/rpds_py-0.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f149826d742b406579466283769a8ea448eed82a789af0ed17b0cd5770433444", size = 423713, upload-time = "2025-08-27T12:13:21.436Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/ba/3c4978b54a73ed19a7d74531be37a8bcc542d917c770e14d372b8daea186/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:80c60cfb5310677bd67cb1e85a1e8eb52e12529545441b43e6f14d90b878775a", size = 562324, upload-time = "2025-08-27T12:13:22.789Z" },
+ { url = "https://files.pythonhosted.org/packages/b5/6c/6943a91768fec16db09a42b08644b960cff540c66aab89b74be6d4a144ba/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7ee6521b9baf06085f62ba9c7a3e5becffbc32480d2f1b351559c001c38ce4c1", size = 593646, upload-time = "2025-08-27T12:13:24.122Z" },
+ { url = "https://files.pythonhosted.org/packages/11/73/9d7a8f4be5f4396f011a6bb7a19fe26303a0dac9064462f5651ced2f572f/rpds_py-0.27.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a512c8263249a9d68cac08b05dd59d2b3f2061d99b322813cbcc14c3c7421998", size = 558137, upload-time = "2025-08-27T12:13:25.557Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/96/6772cbfa0e2485bcceef8071de7821f81aeac8bb45fbfd5542a3e8108165/rpds_py-0.27.1-cp312-cp312-win32.whl", hash = "sha256:819064fa048ba01b6dadc5116f3ac48610435ac9a0058bbde98e569f9e785c39", size = 221343, upload-time = "2025-08-27T12:13:26.967Z" },
+ { url = "https://files.pythonhosted.org/packages/67/b6/c82f0faa9af1c6a64669f73a17ee0eeef25aff30bb9a1c318509efe45d84/rpds_py-0.27.1-cp312-cp312-win_amd64.whl", hash = "sha256:d9199717881f13c32c4046a15f024971a3b78ad4ea029e8da6b86e5aa9cf4594", size = 232497, upload-time = "2025-08-27T12:13:28.326Z" },
+ { url = "https://files.pythonhosted.org/packages/e1/96/2817b44bd2ed11aebacc9251da03689d56109b9aba5e311297b6902136e2/rpds_py-0.27.1-cp312-cp312-win_arm64.whl", hash = "sha256:33aa65b97826a0e885ef6e278fbd934e98cdcfed80b63946025f01e2f5b29502", size = 222790, upload-time = "2025-08-27T12:13:29.71Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/77/610aeee8d41e39080c7e14afa5387138e3c9fa9756ab893d09d99e7d8e98/rpds_py-0.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:e4b9fcfbc021633863a37e92571d6f91851fa656f0180246e84cbd8b3f6b329b", size = 361741, upload-time = "2025-08-27T12:13:31.039Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/fc/c43765f201c6a1c60be2043cbdb664013def52460a4c7adace89d6682bf4/rpds_py-0.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1441811a96eadca93c517d08df75de45e5ffe68aa3089924f963c782c4b898cf", size = 345574, upload-time = "2025-08-27T12:13:32.902Z" },
+ { url = "https://files.pythonhosted.org/packages/20/42/ee2b2ca114294cd9847d0ef9c26d2b0851b2e7e00bf14cc4c0b581df0fc3/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55266dafa22e672f5a4f65019015f90336ed31c6383bd53f5e7826d21a0e0b83", size = 385051, upload-time = "2025-08-27T12:13:34.228Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/e8/1e430fe311e4799e02e2d1af7c765f024e95e17d651612425b226705f910/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78827d7ac08627ea2c8e02c9e5b41180ea5ea1f747e9db0915e3adf36b62dcf", size = 398395, upload-time = "2025-08-27T12:13:36.132Z" },
+ { url = "https://files.pythonhosted.org/packages/82/95/9dc227d441ff2670651c27a739acb2535ccaf8b351a88d78c088965e5996/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae92443798a40a92dc5f0b01d8a7c93adde0c4dc965310a29ae7c64d72b9fad2", size = 524334, upload-time = "2025-08-27T12:13:37.562Z" },
+ { url = "https://files.pythonhosted.org/packages/87/01/a670c232f401d9ad461d9a332aa4080cd3cb1d1df18213dbd0d2a6a7ab51/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c46c9dd2403b66a2a3b9720ec4b74d4ab49d4fabf9f03dfdce2d42af913fe8d0", size = 407691, upload-time = "2025-08-27T12:13:38.94Z" },
+ { url = "https://files.pythonhosted.org/packages/03/36/0a14aebbaa26fe7fab4780c76f2239e76cc95a0090bdb25e31d95c492fcd/rpds_py-0.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2efe4eb1d01b7f5f1939f4ef30ecea6c6b3521eec451fb93191bf84b2a522418", size = 386868, upload-time = "2025-08-27T12:13:40.192Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/03/8c897fb8b5347ff6c1cc31239b9611c5bf79d78c984430887a353e1409a1/rpds_py-0.27.1-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:15d3b4d83582d10c601f481eca29c3f138d44c92187d197aff663a269197c02d", size = 405469, upload-time = "2025-08-27T12:13:41.496Z" },
+ { url = "https://files.pythonhosted.org/packages/da/07/88c60edc2df74850d496d78a1fdcdc7b54360a7f610a4d50008309d41b94/rpds_py-0.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ed2e16abbc982a169d30d1a420274a709949e2cbdef119fe2ec9d870b42f274", size = 422125, upload-time = "2025-08-27T12:13:42.802Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/86/5f4c707603e41b05f191a749984f390dabcbc467cf833769b47bf14ba04f/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a75f305c9b013289121ec0f1181931975df78738cdf650093e6b86d74aa7d8dd", size = 562341, upload-time = "2025-08-27T12:13:44.472Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/92/3c0cb2492094e3cd9baf9e49bbb7befeceb584ea0c1a8b5939dca4da12e5/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:67ce7620704745881a3d4b0ada80ab4d99df390838839921f99e63c474f82cf2", size = 592511, upload-time = "2025-08-27T12:13:45.898Z" },
+ { url = "https://files.pythonhosted.org/packages/10/bb/82e64fbb0047c46a168faa28d0d45a7851cd0582f850b966811d30f67ad8/rpds_py-0.27.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d992ac10eb86d9b6f369647b6a3f412fc0075cfd5d799530e84d335e440a002", size = 557736, upload-time = "2025-08-27T12:13:47.408Z" },
+ { url = "https://files.pythonhosted.org/packages/00/95/3c863973d409210da7fb41958172c6b7dbe7fc34e04d3cc1f10bb85e979f/rpds_py-0.27.1-cp313-cp313-win32.whl", hash = "sha256:4f75e4bd8ab8db624e02c8e2fc4063021b58becdbe6df793a8111d9343aec1e3", size = 221462, upload-time = "2025-08-27T12:13:48.742Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/2c/5867b14a81dc217b56d95a9f2a40fdbc56a1ab0181b80132beeecbd4b2d6/rpds_py-0.27.1-cp313-cp313-win_amd64.whl", hash = "sha256:f9025faafc62ed0b75a53e541895ca272815bec18abe2249ff6501c8f2e12b83", size = 232034, upload-time = "2025-08-27T12:13:50.11Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/78/3958f3f018c01923823f1e47f1cc338e398814b92d83cd278364446fac66/rpds_py-0.27.1-cp313-cp313-win_arm64.whl", hash = "sha256:ed10dc32829e7d222b7d3b93136d25a406ba9788f6a7ebf6809092da1f4d279d", size = 222392, upload-time = "2025-08-27T12:13:52.587Z" },
+ { url = "https://files.pythonhosted.org/packages/01/76/1cdf1f91aed5c3a7bf2eba1f1c4e4d6f57832d73003919a20118870ea659/rpds_py-0.27.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:92022bbbad0d4426e616815b16bc4127f83c9a74940e1ccf3cfe0b387aba0228", size = 358355, upload-time = "2025-08-27T12:13:54.012Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/6f/bf142541229374287604caf3bb2a4ae17f0a580798fd72d3b009b532db4e/rpds_py-0.27.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:47162fdab9407ec3f160805ac3e154df042e577dd53341745fc7fb3f625e6d92", size = 342138, upload-time = "2025-08-27T12:13:55.791Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/77/355b1c041d6be40886c44ff5e798b4e2769e497b790f0f7fd1e78d17e9a8/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb89bec23fddc489e5d78b550a7b773557c9ab58b7946154a10a6f7a214a48b2", size = 380247, upload-time = "2025-08-27T12:13:57.683Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/a4/d9cef5c3946ea271ce2243c51481971cd6e34f21925af2783dd17b26e815/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e48af21883ded2b3e9eb48cb7880ad8598b31ab752ff3be6457001d78f416723", size = 390699, upload-time = "2025-08-27T12:13:59.137Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/06/005106a7b8c6c1a7e91b73169e49870f4af5256119d34a361ae5240a0c1d/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6f5b7bd8e219ed50299e58551a410b64daafb5017d54bbe822e003856f06a802", size = 521852, upload-time = "2025-08-27T12:14:00.583Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/3e/50fb1dac0948e17a02eb05c24510a8fe12d5ce8561c6b7b7d1339ab7ab9c/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08f1e20bccf73b08d12d804d6e1c22ca5530e71659e6673bce31a6bb71c1e73f", size = 402582, upload-time = "2025-08-27T12:14:02.034Z" },
+ { url = "https://files.pythonhosted.org/packages/cb/b0/f4e224090dc5b0ec15f31a02d746ab24101dd430847c4d99123798661bfc/rpds_py-0.27.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dc5dceeaefcc96dc192e3a80bbe1d6c410c469e97bdd47494a7d930987f18b2", size = 384126, upload-time = "2025-08-27T12:14:03.437Z" },
+ { url = "https://files.pythonhosted.org/packages/54/77/ac339d5f82b6afff1df8f0fe0d2145cc827992cb5f8eeb90fc9f31ef7a63/rpds_py-0.27.1-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:d76f9cc8665acdc0c9177043746775aa7babbf479b5520b78ae4002d889f5c21", size = 399486, upload-time = "2025-08-27T12:14:05.443Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/29/3e1c255eee6ac358c056a57d6d6869baa00a62fa32eea5ee0632039c50a3/rpds_py-0.27.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:134fae0e36022edad8290a6661edf40c023562964efea0cc0ec7f5d392d2aaef", size = 414832, upload-time = "2025-08-27T12:14:06.902Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/db/6d498b844342deb3fa1d030598db93937a9964fcf5cb4da4feb5f17be34b/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb11a4f1b2b63337cfd3b4d110af778a59aae51c81d195768e353d8b52f88081", size = 557249, upload-time = "2025-08-27T12:14:08.37Z" },
+ { url = "https://files.pythonhosted.org/packages/60/f3/690dd38e2310b6f68858a331399b4d6dbb9132c3e8ef8b4333b96caf403d/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:13e608ac9f50a0ed4faec0e90ece76ae33b34c0e8656e3dceb9a7db994c692cd", size = 587356, upload-time = "2025-08-27T12:14:10.034Z" },
+ { url = "https://files.pythonhosted.org/packages/86/e3/84507781cccd0145f35b1dc32c72675200c5ce8d5b30f813e49424ef68fc/rpds_py-0.27.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dd2135527aa40f061350c3f8f89da2644de26cd73e4de458e79606384f4f68e7", size = 555300, upload-time = "2025-08-27T12:14:11.783Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/ee/375469849e6b429b3516206b4580a79e9ef3eb12920ddbd4492b56eaacbe/rpds_py-0.27.1-cp313-cp313t-win32.whl", hash = "sha256:3020724ade63fe320a972e2ffd93b5623227e684315adce194941167fee02688", size = 216714, upload-time = "2025-08-27T12:14:13.629Z" },
+ { url = "https://files.pythonhosted.org/packages/21/87/3fc94e47c9bd0742660e84706c311a860dcae4374cf4a03c477e23ce605a/rpds_py-0.27.1-cp313-cp313t-win_amd64.whl", hash = "sha256:8ee50c3e41739886606388ba3ab3ee2aae9f35fb23f833091833255a31740797", size = 228943, upload-time = "2025-08-27T12:14:14.937Z" },
+ { url = "https://files.pythonhosted.org/packages/70/36/b6e6066520a07cf029d385de869729a895917b411e777ab1cde878100a1d/rpds_py-0.27.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:acb9aafccaae278f449d9c713b64a9e68662e7799dbd5859e2c6b3c67b56d334", size = 362472, upload-time = "2025-08-27T12:14:16.333Z" },
+ { url = "https://files.pythonhosted.org/packages/af/07/b4646032e0dcec0df9c73a3bd52f63bc6c5f9cda992f06bd0e73fe3fbebd/rpds_py-0.27.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b7fb801aa7f845ddf601c49630deeeccde7ce10065561d92729bfe81bd21fb33", size = 345676, upload-time = "2025-08-27T12:14:17.764Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/16/2f1003ee5d0af4bcb13c0cf894957984c32a6751ed7206db2aee7379a55e/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe0dd05afb46597b9a2e11c351e5e4283c741237e7f617ffb3252780cca9336a", size = 385313, upload-time = "2025-08-27T12:14:19.829Z" },
+ { url = "https://files.pythonhosted.org/packages/05/cd/7eb6dd7b232e7f2654d03fa07f1414d7dfc980e82ba71e40a7c46fd95484/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b6dfb0e058adb12d8b1d1b25f686e94ffa65d9995a5157afe99743bf7369d62b", size = 399080, upload-time = "2025-08-27T12:14:21.531Z" },
+ { url = "https://files.pythonhosted.org/packages/20/51/5829afd5000ec1cb60f304711f02572d619040aa3ec033d8226817d1e571/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed090ccd235f6fa8bb5861684567f0a83e04f52dfc2e5c05f2e4b1309fcf85e7", size = 523868, upload-time = "2025-08-27T12:14:23.485Z" },
+ { url = "https://files.pythonhosted.org/packages/05/2c/30eebca20d5db95720ab4d2faec1b5e4c1025c473f703738c371241476a2/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf876e79763eecf3e7356f157540d6a093cef395b65514f17a356f62af6cc136", size = 408750, upload-time = "2025-08-27T12:14:24.924Z" },
+ { url = "https://files.pythonhosted.org/packages/90/1a/cdb5083f043597c4d4276eae4e4c70c55ab5accec078da8611f24575a367/rpds_py-0.27.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12ed005216a51b1d6e2b02a7bd31885fe317e45897de81d86dcce7d74618ffff", size = 387688, upload-time = "2025-08-27T12:14:27.537Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/92/cf786a15320e173f945d205ab31585cc43969743bb1a48b6888f7a2b0a2d/rpds_py-0.27.1-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:ee4308f409a40e50593c7e3bb8cbe0b4d4c66d1674a316324f0c2f5383b486f9", size = 407225, upload-time = "2025-08-27T12:14:28.981Z" },
+ { url = "https://files.pythonhosted.org/packages/33/5c/85ee16df5b65063ef26017bef33096557a4c83fbe56218ac7cd8c235f16d/rpds_py-0.27.1-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b08d152555acf1f455154d498ca855618c1378ec810646fcd7c76416ac6dc60", size = 423361, upload-time = "2025-08-27T12:14:30.469Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/8e/1c2741307fcabd1a334ecf008e92c4f47bb6f848712cf15c923becfe82bb/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dce51c828941973a5684d458214d3a36fcd28da3e1875d659388f4f9f12cc33e", size = 562493, upload-time = "2025-08-27T12:14:31.987Z" },
+ { url = "https://files.pythonhosted.org/packages/04/03/5159321baae9b2222442a70c1f988cbbd66b9be0675dd3936461269be360/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:c1476d6f29eb81aa4151c9a31219b03f1f798dc43d8af1250a870735516a1212", size = 592623, upload-time = "2025-08-27T12:14:33.543Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/39/c09fd1ad28b85bc1d4554a8710233c9f4cefd03d7717a1b8fbfd171d1167/rpds_py-0.27.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3ce0cac322b0d69b63c9cdb895ee1b65805ec9ffad37639f291dd79467bee675", size = 558800, upload-time = "2025-08-27T12:14:35.436Z" },
+ { url = "https://files.pythonhosted.org/packages/c5/d6/99228e6bbcf4baa764b18258f519a9035131d91b538d4e0e294313462a98/rpds_py-0.27.1-cp314-cp314-win32.whl", hash = "sha256:dfbfac137d2a3d0725758cd141f878bf4329ba25e34979797c89474a89a8a3a3", size = 221943, upload-time = "2025-08-27T12:14:36.898Z" },
+ { url = "https://files.pythonhosted.org/packages/be/07/c802bc6b8e95be83b79bdf23d1aa61d68324cb1006e245d6c58e959e314d/rpds_py-0.27.1-cp314-cp314-win_amd64.whl", hash = "sha256:a6e57b0abfe7cc513450fcf529eb486b6e4d3f8aee83e92eb5f1ef848218d456", size = 233739, upload-time = "2025-08-27T12:14:38.386Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/89/3e1b1c16d4c2d547c5717377a8df99aee8099ff050f87c45cb4d5fa70891/rpds_py-0.27.1-cp314-cp314-win_arm64.whl", hash = "sha256:faf8d146f3d476abfee026c4ae3bdd9ca14236ae4e4c310cbd1cf75ba33d24a3", size = 223120, upload-time = "2025-08-27T12:14:39.82Z" },
+ { url = "https://files.pythonhosted.org/packages/62/7e/dc7931dc2fa4a6e46b2a4fa744a9fe5c548efd70e0ba74f40b39fa4a8c10/rpds_py-0.27.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:ba81d2b56b6d4911ce735aad0a1d4495e808b8ee4dc58715998741a26874e7c2", size = 358944, upload-time = "2025-08-27T12:14:41.199Z" },
+ { url = "https://files.pythonhosted.org/packages/e6/22/4af76ac4e9f336bfb1a5f240d18a33c6b2fcaadb7472ac7680576512b49a/rpds_py-0.27.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:84f7d509870098de0e864cad0102711c1e24e9b1a50ee713b65928adb22269e4", size = 342283, upload-time = "2025-08-27T12:14:42.699Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/15/2a7c619b3c2272ea9feb9ade67a45c40b3eeb500d503ad4c28c395dc51b4/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9e960fc78fecd1100539f14132425e1d5fe44ecb9239f8f27f079962021523e", size = 380320, upload-time = "2025-08-27T12:14:44.157Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/7d/4c6d243ba4a3057e994bb5bedd01b5c963c12fe38dde707a52acdb3849e7/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:62f85b665cedab1a503747617393573995dac4600ff51869d69ad2f39eb5e817", size = 391760, upload-time = "2025-08-27T12:14:45.845Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/71/b19401a909b83bcd67f90221330bc1ef11bc486fe4e04c24388d28a618ae/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fed467af29776f6556250c9ed85ea5a4dd121ab56a5f8b206e3e7a4c551e48ec", size = 522476, upload-time = "2025-08-27T12:14:47.364Z" },
+ { url = "https://files.pythonhosted.org/packages/e4/44/1a3b9715c0455d2e2f0f6df5ee6d6f5afdc423d0773a8a682ed2b43c566c/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2729615f9d430af0ae6b36cf042cb55c0936408d543fb691e1a9e36648fd35a", size = 403418, upload-time = "2025-08-27T12:14:49.991Z" },
+ { url = "https://files.pythonhosted.org/packages/1c/4b/fb6c4f14984eb56673bc868a66536f53417ddb13ed44b391998100a06a96/rpds_py-0.27.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b207d881a9aef7ba753d69c123a35d96ca7cb808056998f6b9e8747321f03b8", size = 384771, upload-time = "2025-08-27T12:14:52.159Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/56/d5265d2d28b7420d7b4d4d85cad8ef891760f5135102e60d5c970b976e41/rpds_py-0.27.1-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:639fd5efec029f99b79ae47e5d7e00ad8a773da899b6309f6786ecaf22948c48", size = 400022, upload-time = "2025-08-27T12:14:53.859Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/e9/9f5fc70164a569bdd6ed9046486c3568d6926e3a49bdefeeccfb18655875/rpds_py-0.27.1-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fecc80cb2a90e28af8a9b366edacf33d7a91cbfe4c2c4544ea1246e949cfebeb", size = 416787, upload-time = "2025-08-27T12:14:55.673Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/64/56dd03430ba491db943a81dcdef115a985aac5f44f565cd39a00c766d45c/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42a89282d711711d0a62d6f57d81aa43a1368686c45bc1c46b7f079d55692734", size = 557538, upload-time = "2025-08-27T12:14:57.245Z" },
+ { url = "https://files.pythonhosted.org/packages/3f/36/92cc885a3129993b1d963a2a42ecf64e6a8e129d2c7cc980dbeba84e55fb/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:cf9931f14223de59551ab9d38ed18d92f14f055a5f78c1d8ad6493f735021bbb", size = 588512, upload-time = "2025-08-27T12:14:58.728Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/10/6b283707780a81919f71625351182b4f98932ac89a09023cb61865136244/rpds_py-0.27.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f39f58a27cc6e59f432b568ed8429c7e1641324fbe38131de852cd77b2d534b0", size = 555813, upload-time = "2025-08-27T12:15:00.334Z" },
+ { url = "https://files.pythonhosted.org/packages/04/2e/30b5ea18c01379da6272a92825dd7e53dc9d15c88a19e97932d35d430ef7/rpds_py-0.27.1-cp314-cp314t-win32.whl", hash = "sha256:d5fa0ee122dc09e23607a28e6d7b150da16c662e66409bbe85230e4c85bb528a", size = 217385, upload-time = "2025-08-27T12:15:01.937Z" },
+ { url = "https://files.pythonhosted.org/packages/32/7d/97119da51cb1dd3f2f3c0805f155a3aa4a95fa44fe7d78ae15e69edf4f34/rpds_py-0.27.1-cp314-cp314t-win_amd64.whl", hash = "sha256:6567d2bb951e21232c2f660c24cf3470bb96de56cdcb3f071a83feeaff8a2772", size = 230097, upload-time = "2025-08-27T12:15:03.961Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/6c/252e83e1ce7583c81f26d1d884b2074d40a13977e1b6c9c50bbf9a7f1f5a/rpds_py-0.27.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:c918c65ec2e42c2a78d19f18c553d77319119bf43aa9e2edf7fb78d624355527", size = 372140, upload-time = "2025-08-27T12:15:05.441Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/71/949c195d927c5aeb0d0629d329a20de43a64c423a6aa53836290609ef7ec/rpds_py-0.27.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1fea2b1a922c47c51fd07d656324531adc787e415c8b116530a1d29c0516c62d", size = 354086, upload-time = "2025-08-27T12:15:07.404Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/02/e43e332ad8ce4f6c4342d151a471a7f2900ed1d76901da62eb3762663a71/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbf94c58e8e0cd6b6f38d8de67acae41b3a515c26169366ab58bdca4a6883bb8", size = 382117, upload-time = "2025-08-27T12:15:09.275Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/05/b0fdeb5b577197ad72812bbdfb72f9a08fa1e64539cc3940b1b781cd3596/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c2a8fed130ce946d5c585eddc7c8eeef0051f58ac80a8ee43bd17835c144c2cc", size = 394520, upload-time = "2025-08-27T12:15:10.727Z" },
+ { url = "https://files.pythonhosted.org/packages/67/1f/4cfef98b2349a7585181e99294fa2a13f0af06902048a5d70f431a66d0b9/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:037a2361db72ee98d829bc2c5b7cc55598ae0a5e0ec1823a56ea99374cfd73c1", size = 522657, upload-time = "2025-08-27T12:15:12.613Z" },
+ { url = "https://files.pythonhosted.org/packages/44/55/ccf37ddc4c6dce7437b335088b5ca18da864b334890e2fe9aa6ddc3f79a9/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5281ed1cc1d49882f9997981c88df1a22e140ab41df19071222f7e5fc4e72125", size = 402967, upload-time = "2025-08-27T12:15:14.113Z" },
+ { url = "https://files.pythonhosted.org/packages/74/e5/5903f92e41e293b07707d5bf00ef39a0eb2af7190aff4beaf581a6591510/rpds_py-0.27.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fd50659a069c15eef8aa3d64bbef0d69fd27bb4a50c9ab4f17f83a16cbf8905", size = 384372, upload-time = "2025-08-27T12:15:15.842Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/e3/fbb409e18aeefc01e49f5922ac63d2d914328430e295c12183ce56ebf76b/rpds_py-0.27.1-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:c4b676c4ae3921649a15d28ed10025548e9b561ded473aa413af749503c6737e", size = 401264, upload-time = "2025-08-27T12:15:17.388Z" },
+ { url = "https://files.pythonhosted.org/packages/55/79/529ad07794e05cb0f38e2f965fc5bb20853d523976719400acecc447ec9d/rpds_py-0.27.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:079bc583a26db831a985c5257797b2b5d3affb0386e7ff886256762f82113b5e", size = 418691, upload-time = "2025-08-27T12:15:19.144Z" },
+ { url = "https://files.pythonhosted.org/packages/33/39/6554a7fd6d9906fda2521c6d52f5d723dca123529fb719a5b5e074c15e01/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4e44099bd522cba71a2c6b97f68e19f40e7d85399de899d66cdb67b32d7cb786", size = 558989, upload-time = "2025-08-27T12:15:21.087Z" },
+ { url = "https://files.pythonhosted.org/packages/19/b2/76fa15173b6f9f445e5ef15120871b945fb8dd9044b6b8c7abe87e938416/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e202e6d4188e53c6661af813b46c37ca2c45e497fc558bacc1a7630ec2695aec", size = 589835, upload-time = "2025-08-27T12:15:22.696Z" },
+ { url = "https://files.pythonhosted.org/packages/ee/9e/5560a4b39bab780405bed8a88ee85b30178061d189558a86003548dea045/rpds_py-0.27.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f41f814b8eaa48768d1bb551591f6ba45f87ac76899453e8ccd41dba1289b04b", size = 555227, upload-time = "2025-08-27T12:15:24.278Z" },
+ { url = "https://files.pythonhosted.org/packages/52/d7/cd9c36215111aa65724c132bf709c6f35175973e90b32115dedc4ced09cb/rpds_py-0.27.1-cp39-cp39-win32.whl", hash = "sha256:9e71f5a087ead99563c11fdaceee83ee982fd39cf67601f4fd66cb386336ee52", size = 217899, upload-time = "2025-08-27T12:15:25.926Z" },
+ { url = "https://files.pythonhosted.org/packages/5b/e0/d75ab7b4dd8ba777f6b365adbdfc7614bbfe7c5f05703031dfa4b61c3d6c/rpds_py-0.27.1-cp39-cp39-win_amd64.whl", hash = "sha256:71108900c9c3c8590697244b9519017a400d9ba26a36c48381b3f64743a44aab", size = 228725, upload-time = "2025-08-27T12:15:27.398Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/63/b7cc415c345625d5e62f694ea356c58fb964861409008118f1245f8c3347/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7ba22cb9693df986033b91ae1d7a979bc399237d45fccf875b76f62bb9e52ddf", size = 371360, upload-time = "2025-08-27T12:15:29.218Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/8c/12e1b24b560cf378b8ffbdb9dc73abd529e1adcfcf82727dfd29c4a7b88d/rpds_py-0.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b640501be9288c77738b5492b3fd3abc4ba95c50c2e41273c8a1459f08298d3", size = 353933, upload-time = "2025-08-27T12:15:30.837Z" },
+ { url = "https://files.pythonhosted.org/packages/9b/85/1bb2210c1f7a1b99e91fea486b9f0f894aa5da3a5ec7097cbad7dec6d40f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb08b65b93e0c6dd70aac7f7890a9c0938d5ec71d5cb32d45cf844fb8ae47636", size = 382962, upload-time = "2025-08-27T12:15:32.348Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/c9/a839b9f219cf80ed65f27a7f5ddbb2809c1b85c966020ae2dff490e0b18e/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d7ff07d696a7a38152ebdb8212ca9e5baab56656749f3d6004b34ab726b550b8", size = 394412, upload-time = "2025-08-27T12:15:33.839Z" },
+ { url = "https://files.pythonhosted.org/packages/02/2d/b1d7f928b0b1f4fc2e0133e8051d199b01d7384875adc63b6ddadf3de7e5/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb7c72262deae25366e3b6c0c0ba46007967aea15d1eea746e44ddba8ec58dcc", size = 523972, upload-time = "2025-08-27T12:15:35.377Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/af/2cbf56edd2d07716df1aec8a726b3159deb47cb5c27e1e42b71d705a7c2f/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b002cab05d6339716b03a4a3a2ce26737f6231d7b523f339fa061d53368c9d8", size = 403273, upload-time = "2025-08-27T12:15:37.051Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/93/425e32200158d44ff01da5d9612c3b6711fe69f606f06e3895511f17473b/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23f6b69d1c26c4704fec01311963a41d7de3ee0570a84ebde4d544e5a1859ffc", size = 385278, upload-time = "2025-08-27T12:15:38.571Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/1a/1a04a915ecd0551bfa9e77b7672d1937b4b72a0fc204a17deef76001cfb2/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:530064db9146b247351f2a0250b8f00b289accea4596a033e94be2389977de71", size = 402084, upload-time = "2025-08-27T12:15:40.529Z" },
+ { url = "https://files.pythonhosted.org/packages/51/f7/66585c0fe5714368b62951d2513b684e5215beaceab2c6629549ddb15036/rpds_py-0.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b90b0496570bd6b0321724a330d8b545827c4df2034b6ddfc5f5275f55da2ad", size = 419041, upload-time = "2025-08-27T12:15:42.191Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/7e/83a508f6b8e219bba2d4af077c35ba0e0cdd35a751a3be6a7cba5a55ad71/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:879b0e14a2da6a1102a3fc8af580fc1ead37e6d6692a781bd8c83da37429b5ab", size = 560084, upload-time = "2025-08-27T12:15:43.839Z" },
+ { url = "https://files.pythonhosted.org/packages/66/66/bb945683b958a1b19eb0fe715594630d0f36396ebdef4d9b89c2fa09aa56/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:0d807710df3b5faa66c731afa162ea29717ab3be17bdc15f90f2d9f183da4059", size = 590115, upload-time = "2025-08-27T12:15:46.647Z" },
+ { url = "https://files.pythonhosted.org/packages/12/00/ccfaafaf7db7e7adace915e5c2f2c2410e16402561801e9c7f96683002d3/rpds_py-0.27.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:3adc388fc3afb6540aec081fa59e6e0d3908722771aa1e37ffe22b220a436f0b", size = 556561, upload-time = "2025-08-27T12:15:48.219Z" },
+ { url = "https://files.pythonhosted.org/packages/e1/b7/92b6ed9aad103bfe1c45df98453dfae40969eef2cb6c6239c58d7e96f1b3/rpds_py-0.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:c796c0c1cc68cb08b0284db4229f5af76168172670c74908fdbd4b7d7f515819", size = 229125, upload-time = "2025-08-27T12:15:49.956Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/ed/e1fba02de17f4f76318b834425257c8ea297e415e12c68b4361f63e8ae92/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdfe4bb2f9fe7458b7453ad3c33e726d6d1c7c0a72960bcc23800d77384e42df", size = 371402, upload-time = "2025-08-27T12:15:51.561Z" },
+ { url = "https://files.pythonhosted.org/packages/af/7c/e16b959b316048b55585a697e94add55a4ae0d984434d279ea83442e460d/rpds_py-0.27.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8fabb8fd848a5f75a2324e4a84501ee3a5e3c78d8603f83475441866e60b94a3", size = 354084, upload-time = "2025-08-27T12:15:53.219Z" },
+ { url = "https://files.pythonhosted.org/packages/de/c1/ade645f55de76799fdd08682d51ae6724cb46f318573f18be49b1e040428/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eda8719d598f2f7f3e0f885cba8646644b55a187762bec091fa14a2b819746a9", size = 383090, upload-time = "2025-08-27T12:15:55.158Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/27/89070ca9b856e52960da1472efcb6c20ba27cfe902f4f23ed095b9cfc61d/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c64d07e95606ec402a0a1c511fe003873fa6af630bda59bac77fac8b4318ebc", size = 394519, upload-time = "2025-08-27T12:15:57.238Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/28/be120586874ef906aa5aeeae95ae8df4184bc757e5b6bd1c729ccff45ed5/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:93a2ed40de81bcff59aabebb626562d48332f3d028ca2036f1d23cbb52750be4", size = 523817, upload-time = "2025-08-27T12:15:59.237Z" },
+ { url = "https://files.pythonhosted.org/packages/a8/ef/70cc197bc11cfcde02a86f36ac1eed15c56667c2ebddbdb76a47e90306da/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387ce8c44ae94e0ec50532d9cb0edce17311024c9794eb196b90e1058aadeb66", size = 403240, upload-time = "2025-08-27T12:16:00.923Z" },
+ { url = "https://files.pythonhosted.org/packages/cf/35/46936cca449f7f518f2f4996e0e8344db4b57e2081e752441154089d2a5f/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaf94f812c95b5e60ebaf8bfb1898a7d7cb9c1af5744d4a67fa47796e0465d4e", size = 385194, upload-time = "2025-08-27T12:16:02.802Z" },
+ { url = "https://files.pythonhosted.org/packages/e1/62/29c0d3e5125c3270b51415af7cbff1ec587379c84f55a5761cc9efa8cd06/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:4848ca84d6ded9b58e474dfdbad4b8bfb450344c0551ddc8d958bf4b36aa837c", size = 402086, upload-time = "2025-08-27T12:16:04.806Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/66/03e1087679227785474466fdd04157fb793b3b76e3fcf01cbf4c693c1949/rpds_py-0.27.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2bde09cbcf2248b73c7c323be49b280180ff39fadcfe04e7b6f54a678d02a7cf", size = 419272, upload-time = "2025-08-27T12:16:06.471Z" },
+ { url = "https://files.pythonhosted.org/packages/6a/24/e3e72d265121e00b063aef3e3501e5b2473cf1b23511d56e529531acf01e/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:94c44ee01fd21c9058f124d2d4f0c9dc7634bec93cd4b38eefc385dabe71acbf", size = 560003, upload-time = "2025-08-27T12:16:08.06Z" },
+ { url = "https://files.pythonhosted.org/packages/26/ca/f5a344c534214cc2d41118c0699fffbdc2c1bc7046f2a2b9609765ab9c92/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_i686.whl", hash = "sha256:df8b74962e35c9249425d90144e721eed198e6555a0e22a563d29fe4486b51f6", size = 590482, upload-time = "2025-08-27T12:16:10.137Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/08/4349bdd5c64d9d193c360aa9db89adeee6f6682ab8825dca0a3f535f434f/rpds_py-0.27.1-pp311-pypy311_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:dc23e6820e3b40847e2f4a7726462ba0cf53089512abe9ee16318c366494c17a", size = 556523, upload-time = "2025-08-27T12:16:12.188Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/ea/5463cd5048a7a2fcdae308b6e96432802132c141bfb9420260142632a0f1/rpds_py-0.27.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:aa8933159edc50be265ed22b401125c9eebff3171f570258854dbce3ecd55475", size = 371778, upload-time = "2025-08-27T12:16:13.851Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/c8/f38c099db07f5114029c1467649d308543906933eebbc226d4527a5f4693/rpds_py-0.27.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a50431bf02583e21bf273c71b89d710e7a710ad5e39c725b14e685610555926f", size = 354394, upload-time = "2025-08-27T12:16:15.609Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/79/b76f97704d9dd8ddbd76fed4c4048153a847c5d6003afe20a6b5c3339065/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78af06ddc7fe5cc0e967085a9115accee665fb912c22a3f54bad70cc65b05fe6", size = 382348, upload-time = "2025-08-27T12:16:17.251Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/3f/ef23d3c1be1b837b648a3016d5bbe7cfe711422ad110b4081c0a90ef5a53/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:70d0738ef8fee13c003b100c2fbd667ec4f133468109b3472d249231108283a3", size = 394159, upload-time = "2025-08-27T12:16:19.251Z" },
+ { url = "https://files.pythonhosted.org/packages/74/8a/9e62693af1a34fd28b1a190d463d12407bd7cf561748cb4745845d9548d3/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2f6fd8a1cea5bbe599b6e78a6e5ee08db434fc8ffea51ff201c8765679698b3", size = 522775, upload-time = "2025-08-27T12:16:20.929Z" },
+ { url = "https://files.pythonhosted.org/packages/36/0d/8d5bb122bf7a60976b54c5c99a739a3819f49f02d69df3ea2ca2aff47d5c/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8177002868d1426305bb5de1e138161c2ec9eb2d939be38291d7c431c4712df8", size = 402633, upload-time = "2025-08-27T12:16:22.548Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/0e/237948c1f425e23e0cf5a566d702652a6e55c6f8fbd332a1792eb7043daf/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:008b839781d6c9bf3b6a8984d1d8e56f0ec46dc56df61fd669c49b58ae800400", size = 384867, upload-time = "2025-08-27T12:16:24.29Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/0a/da0813efcd998d260cbe876d97f55b0f469ada8ba9cbc47490a132554540/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_31_riscv64.whl", hash = "sha256:a55b9132bb1ade6c734ddd2759c8dc132aa63687d259e725221f106b83a0e485", size = 401791, upload-time = "2025-08-27T12:16:25.954Z" },
+ { url = "https://files.pythonhosted.org/packages/51/78/c6c9e8a8aaca416a6f0d1b6b4a6ee35b88fe2c5401d02235d0a056eceed2/rpds_py-0.27.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a46fdec0083a26415f11d5f236b79fa1291c32aaa4a17684d82f7017a1f818b1", size = 419525, upload-time = "2025-08-27T12:16:27.659Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/69/5af37e1d71487cf6d56dd1420dc7e0c2732c1b6ff612aa7a88374061c0a8/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:8a63b640a7845f2bdd232eb0d0a4a2dd939bcdd6c57e6bb134526487f3160ec5", size = 559255, upload-time = "2025-08-27T12:16:29.343Z" },
+ { url = "https://files.pythonhosted.org/packages/40/7f/8b7b136069ef7ac3960eda25d832639bdb163018a34c960ed042dd1707c8/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:7e32721e5d4922deaaf963469d795d5bde6093207c52fec719bd22e5d1bedbc4", size = 590384, upload-time = "2025-08-27T12:16:31.005Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/06/c316d3f6ff03f43ccb0eba7de61376f8ec4ea850067dddfafe98274ae13c/rpds_py-0.27.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:2c426b99a068601b5f4623573df7a7c3d72e87533a2dd2253353a03e7502566c", size = 555959, upload-time = "2025-08-27T12:16:32.73Z" },
+ { url = "https://files.pythonhosted.org/packages/60/94/384cf54c430b9dac742bbd2ec26c23feb78ded0d43d6d78563a281aec017/rpds_py-0.27.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4fc9b7fe29478824361ead6e14e4f5aed570d477e06088826537e202d25fe859", size = 228784, upload-time = "2025-08-27T12:16:34.428Z" },
+]
+
+[[package]]
+name = "ruff"
+version = "0.14.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6ca66896635352812de66f71cdf9ff86b3a4f79071ca5730088c0cd0fc8d/ruff-0.14.1.tar.gz", hash = "sha256:1dd86253060c4772867c61791588627320abcb6ed1577a90ef432ee319729b69", size = 5513429, upload-time = "2025-10-16T18:05:41.766Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8d/39/9cc5ab181478d7a18adc1c1e051a84ee02bec94eb9bdfd35643d7c74ca31/ruff-0.14.1-py3-none-linux_armv6l.whl", hash = "sha256:083bfc1f30f4a391ae09c6f4f99d83074416b471775b59288956f5bc18e82f8b", size = 12445415, upload-time = "2025-10-16T18:04:48.227Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/2e/1226961855ccd697255988f5a2474890ac7c5863b080b15bd038df820818/ruff-0.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f6fa757cd717f791009f7669fefb09121cc5f7d9bd0ef211371fad68c2b8b224", size = 12784267, upload-time = "2025-10-16T18:04:52.515Z" },
+ { url = "https://files.pythonhosted.org/packages/c1/ea/fd9e95863124ed159cd0667ec98449ae461de94acda7101f1acb6066da00/ruff-0.14.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6191903d39ac156921398e9c86b7354d15e3c93772e7dbf26c9fcae59ceccd5", size = 11781872, upload-time = "2025-10-16T18:04:55.396Z" },
+ { url = "https://files.pythonhosted.org/packages/1e/5a/e890f7338ff537dba4589a5e02c51baa63020acfb7c8cbbaea4831562c96/ruff-0.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed04f0e04f7a4587244e5c9d7df50e6b5bf2705d75059f409a6421c593a35896", size = 12226558, upload-time = "2025-10-16T18:04:58.166Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/7a/8ab5c3377f5bf31e167b73651841217542bcc7aa1c19e83030835cc25204/ruff-0.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c9e6cf6cd4acae0febbce29497accd3632fe2025c0c583c8b87e8dbdeae5f61", size = 12187898, upload-time = "2025-10-16T18:05:01.455Z" },
+ { url = "https://files.pythonhosted.org/packages/48/8d/ba7c33aa55406955fc124e62c8259791c3d42e3075a71710fdff9375134f/ruff-0.14.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fa2458527794ecdfbe45f654e42c61f2503a230545a91af839653a0a93dbc6", size = 12939168, upload-time = "2025-10-16T18:05:04.397Z" },
+ { url = "https://files.pythonhosted.org/packages/b4/c2/70783f612b50f66d083380e68cbd1696739d88e9b4f6164230375532c637/ruff-0.14.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39f1c392244e338b21d42ab29b8a6392a722c5090032eb49bb4d6defcdb34345", size = 14386942, upload-time = "2025-10-16T18:05:07.102Z" },
+ { url = "https://files.pythonhosted.org/packages/48/44/cd7abb9c776b66d332119d67f96acf15830d120f5b884598a36d9d3f4d83/ruff-0.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7382fa12a26cce1f95070ce450946bec357727aaa428983036362579eadcc5cf", size = 13990622, upload-time = "2025-10-16T18:05:09.882Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/56/4259b696db12ac152fe472764b4f78bbdd9b477afd9bc3a6d53c01300b37/ruff-0.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0bf2be3ae8521e1093a487c4aa3b455882f139787770698530d28ed3fbb37c", size = 13431143, upload-time = "2025-10-16T18:05:13.46Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/35/266a80d0eb97bd224b3265b9437bd89dde0dcf4faf299db1212e81824e7e/ruff-0.14.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabcaa9ccf8089fb4fdb78d17cc0e28241520f50f4c2e88cb6261ed083d85151", size = 13132844, upload-time = "2025-10-16T18:05:16.1Z" },
+ { url = "https://files.pythonhosted.org/packages/65/6e/d31ce218acc11a8d91ef208e002a31acf315061a85132f94f3df7a252b18/ruff-0.14.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:747d583400f6125ec11a4c14d1c8474bf75d8b419ad22a111a537ec1a952d192", size = 13401241, upload-time = "2025-10-16T18:05:19.395Z" },
+ { url = "https://files.pythonhosted.org/packages/9f/b5/dbc4221bf0b03774b3b2f0d47f39e848d30664157c15b965a14d890637d2/ruff-0.14.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5a6e74c0efd78515a1d13acbfe6c90f0f5bd822aa56b4a6d43a9ffb2ae6e56cd", size = 12132476, upload-time = "2025-10-16T18:05:22.163Z" },
+ { url = "https://files.pythonhosted.org/packages/98/4b/ac99194e790ccd092d6a8b5f341f34b6e597d698e3077c032c502d75ea84/ruff-0.14.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea6a864d2fb41a4b6d5b456ed164302a0d96f4daac630aeba829abfb059d020", size = 12139749, upload-time = "2025-10-16T18:05:25.162Z" },
+ { url = "https://files.pythonhosted.org/packages/47/26/7df917462c3bb5004e6fdfcc505a49e90bcd8a34c54a051953118c00b53a/ruff-0.14.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0826b8764f94229604fa255918d1cc45e583e38c21c203248b0bfc9a0e930be5", size = 12544758, upload-time = "2025-10-16T18:05:28.018Z" },
+ { url = "https://files.pythonhosted.org/packages/64/d0/81e7f0648e9764ad9b51dd4be5e5dac3fcfff9602428ccbae288a39c2c22/ruff-0.14.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cbc52160465913a1a3f424c81c62ac8096b6a491468e7d872cb9444a860bc33d", size = 13221811, upload-time = "2025-10-16T18:05:30.707Z" },
+ { url = "https://files.pythonhosted.org/packages/c3/07/3c45562c67933cc35f6d5df4ca77dabbcd88fddaca0d6b8371693d29fd56/ruff-0.14.1-py3-none-win32.whl", hash = "sha256:e037ea374aaaff4103240ae79168c0945ae3d5ae8db190603de3b4012bd1def6", size = 12319467, upload-time = "2025-10-16T18:05:33.261Z" },
+ { url = "https://files.pythonhosted.org/packages/02/88/0ee4ca507d4aa05f67e292d2e5eb0b3e358fbcfe527554a2eda9ac422d6b/ruff-0.14.1-py3-none-win_amd64.whl", hash = "sha256:59d599cdff9c7f925a017f6f2c256c908b094e55967f93f2821b1439928746a1", size = 13401123, upload-time = "2025-10-16T18:05:35.984Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/81/4b6387be7014858d924b843530e1b2a8e531846807516e9bea2ee0936bf7/ruff-0.14.1-py3-none-win_arm64.whl", hash = "sha256:e3b443c4c9f16ae850906b8d0a707b2a4c16f8d2f0a7fe65c475c5886665ce44", size = 12436636, upload-time = "2025-10-16T18:05:38.995Z" },
+]
+
+[[package]]
+name = "setuptools"
+version = "80.9.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" },
+]
+
+[[package]]
+name = "six"
+version = "1.17.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
+]
+
+[[package]]
+name = "sortedcontainers"
+version = "2.4.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" },
+]
+
+[[package]]
+name = "tomli"
+version = "2.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/52/ed/3f73f72945444548f33eba9a87fc7a6e969915e7b1acc8260b30e1f76a2f/tomli-2.3.0.tar.gz", hash = "sha256:64be704a875d2a59753d80ee8a533c3fe183e3f06807ff7dc2232938ccb01549", size = 17392, upload-time = "2025-10-08T22:01:47.119Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/b3/2e/299f62b401438d5fe1624119c723f5d877acc86a4c2492da405626665f12/tomli-2.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:88bd15eb972f3664f5ed4b57c1634a97153b4bac4479dcb6a495f41921eb7f45", size = 153236, upload-time = "2025-10-08T22:01:00.137Z" },
+ { url = "https://files.pythonhosted.org/packages/86/7f/d8fffe6a7aefdb61bced88fcb5e280cfd71e08939da5894161bd71bea022/tomli-2.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:883b1c0d6398a6a9d29b508c331fa56adbcdff647f6ace4dfca0f50e90dfd0ba", size = 148084, upload-time = "2025-10-08T22:01:01.63Z" },
+ { url = "https://files.pythonhosted.org/packages/47/5c/24935fb6a2ee63e86d80e4d3b58b222dafaf438c416752c8b58537c8b89a/tomli-2.3.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1381caf13ab9f300e30dd8feadb3de072aeb86f1d34a8569453ff32a7dea4bf", size = 234832, upload-time = "2025-10-08T22:01:02.543Z" },
+ { url = "https://files.pythonhosted.org/packages/89/da/75dfd804fc11e6612846758a23f13271b76d577e299592b4371a4ca4cd09/tomli-2.3.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a0e285d2649b78c0d9027570d4da3425bdb49830a6156121360b3f8511ea3441", size = 242052, upload-time = "2025-10-08T22:01:03.836Z" },
+ { url = "https://files.pythonhosted.org/packages/70/8c/f48ac899f7b3ca7eb13af73bacbc93aec37f9c954df3c08ad96991c8c373/tomli-2.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a154a9ae14bfcf5d8917a59b51ffd5a3ac1fd149b71b47a3a104ca4edcfa845", size = 239555, upload-time = "2025-10-08T22:01:04.834Z" },
+ { url = "https://files.pythonhosted.org/packages/ba/28/72f8afd73f1d0e7829bfc093f4cb98ce0a40ffc0cc997009ee1ed94ba705/tomli-2.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:74bf8464ff93e413514fefd2be591c3b0b23231a77f901db1eb30d6f712fc42c", size = 245128, upload-time = "2025-10-08T22:01:05.84Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/eb/a7679c8ac85208706d27436e8d421dfa39d4c914dcf5fa8083a9305f58d9/tomli-2.3.0-cp311-cp311-win32.whl", hash = "sha256:00b5f5d95bbfc7d12f91ad8c593a1659b6387b43f054104cda404be6bda62456", size = 96445, upload-time = "2025-10-08T22:01:06.896Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/fe/3d3420c4cb1ad9cb462fb52967080575f15898da97e21cb6f1361d505383/tomli-2.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:4dc4ce8483a5d429ab602f111a93a6ab1ed425eae3122032db7e9acf449451be", size = 107165, upload-time = "2025-10-08T22:01:08.107Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/b7/40f36368fcabc518bb11c8f06379a0fd631985046c038aca08c6d6a43c6e/tomli-2.3.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7d86942e56ded512a594786a5ba0a5e521d02529b3826e7761a05138341a2ac", size = 154891, upload-time = "2025-10-08T22:01:09.082Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/3f/d9dd692199e3b3aab2e4e4dd948abd0f790d9ded8cd10cbaae276a898434/tomli-2.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:73ee0b47d4dad1c5e996e3cd33b8a76a50167ae5f96a2607cbe8cc773506ab22", size = 148796, upload-time = "2025-10-08T22:01:10.266Z" },
+ { url = "https://files.pythonhosted.org/packages/60/83/59bff4996c2cf9f9387a0f5a3394629c7efa5ef16142076a23a90f1955fa/tomli-2.3.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:792262b94d5d0a466afb5bc63c7daa9d75520110971ee269152083270998316f", size = 242121, upload-time = "2025-10-08T22:01:11.332Z" },
+ { url = "https://files.pythonhosted.org/packages/45/e5/7c5119ff39de8693d6baab6c0b6dcb556d192c165596e9fc231ea1052041/tomli-2.3.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f195fe57ecceac95a66a75ac24d9d5fbc98ef0962e09b2eddec5d39375aae52", size = 250070, upload-time = "2025-10-08T22:01:12.498Z" },
+ { url = "https://files.pythonhosted.org/packages/45/12/ad5126d3a278f27e6701abde51d342aa78d06e27ce2bb596a01f7709a5a2/tomli-2.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e31d432427dcbf4d86958c184b9bfd1e96b5b71f8eb17e6d02531f434fd335b8", size = 245859, upload-time = "2025-10-08T22:01:13.551Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/a1/4d6865da6a71c603cfe6ad0e6556c73c76548557a8d658f9e3b142df245f/tomli-2.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7b0882799624980785240ab732537fcfc372601015c00f7fc367c55308c186f6", size = 250296, upload-time = "2025-10-08T22:01:14.614Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/b7/a7a7042715d55c9ba6e8b196d65d2cb662578b4d8cd17d882d45322b0d78/tomli-2.3.0-cp312-cp312-win32.whl", hash = "sha256:ff72b71b5d10d22ecb084d345fc26f42b5143c5533db5e2eaba7d2d335358876", size = 97124, upload-time = "2025-10-08T22:01:15.629Z" },
+ { url = "https://files.pythonhosted.org/packages/06/1e/f22f100db15a68b520664eb3328fb0ae4e90530887928558112c8d1f4515/tomli-2.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:1cb4ed918939151a03f33d4242ccd0aa5f11b3547d0cf30f7c74a408a5b99878", size = 107698, upload-time = "2025-10-08T22:01:16.51Z" },
+ { url = "https://files.pythonhosted.org/packages/89/48/06ee6eabe4fdd9ecd48bf488f4ac783844fd777f547b8d1b61c11939974e/tomli-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5192f562738228945d7b13d4930baffda67b69425a7f0da96d360b0a3888136b", size = 154819, upload-time = "2025-10-08T22:01:17.964Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/01/88793757d54d8937015c75dcdfb673c65471945f6be98e6a0410fba167ed/tomli-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:be71c93a63d738597996be9528f4abe628d1adf5e6eb11607bc8fe1a510b5dae", size = 148766, upload-time = "2025-10-08T22:01:18.959Z" },
+ { url = "https://files.pythonhosted.org/packages/42/17/5e2c956f0144b812e7e107f94f1cc54af734eb17b5191c0bbfb72de5e93e/tomli-2.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c4665508bcbac83a31ff8ab08f424b665200c0e1e645d2bd9ab3d3e557b6185b", size = 240771, upload-time = "2025-10-08T22:01:20.106Z" },
+ { url = "https://files.pythonhosted.org/packages/d5/f4/0fbd014909748706c01d16824eadb0307115f9562a15cbb012cd9b3512c5/tomli-2.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4021923f97266babc6ccab9f5068642a0095faa0a51a246a6a02fccbb3514eaf", size = 248586, upload-time = "2025-10-08T22:01:21.164Z" },
+ { url = "https://files.pythonhosted.org/packages/30/77/fed85e114bde5e81ecf9bc5da0cc69f2914b38f4708c80ae67d0c10180c5/tomli-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4ea38c40145a357d513bffad0ed869f13c1773716cf71ccaa83b0fa0cc4e42f", size = 244792, upload-time = "2025-10-08T22:01:22.417Z" },
+ { url = "https://files.pythonhosted.org/packages/55/92/afed3d497f7c186dc71e6ee6d4fcb0acfa5f7d0a1a2878f8beae379ae0cc/tomli-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad805ea85eda330dbad64c7ea7a4556259665bdf9d2672f5dccc740eb9d3ca05", size = 248909, upload-time = "2025-10-08T22:01:23.859Z" },
+ { url = "https://files.pythonhosted.org/packages/f8/84/ef50c51b5a9472e7265ce1ffc7f24cd4023d289e109f669bdb1553f6a7c2/tomli-2.3.0-cp313-cp313-win32.whl", hash = "sha256:97d5eec30149fd3294270e889b4234023f2c69747e555a27bd708828353ab606", size = 96946, upload-time = "2025-10-08T22:01:24.893Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/b7/718cd1da0884f281f95ccfa3a6cc572d30053cba64603f79d431d3c9b61b/tomli-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0c95ca56fbe89e065c6ead5b593ee64b84a26fca063b5d71a1122bf26e533999", size = 107705, upload-time = "2025-10-08T22:01:26.153Z" },
+ { url = "https://files.pythonhosted.org/packages/19/94/aeafa14a52e16163008060506fcb6aa1949d13548d13752171a755c65611/tomli-2.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cebc6fe843e0733ee827a282aca4999b596241195f43b4cc371d64fc6639da9e", size = 154244, upload-time = "2025-10-08T22:01:27.06Z" },
+ { url = "https://files.pythonhosted.org/packages/db/e4/1e58409aa78eefa47ccd19779fc6f36787edbe7d4cd330eeeedb33a4515b/tomli-2.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4c2ef0244c75aba9355561272009d934953817c49f47d768070c3c94355c2aa3", size = 148637, upload-time = "2025-10-08T22:01:28.059Z" },
+ { url = "https://files.pythonhosted.org/packages/26/b6/d1eccb62f665e44359226811064596dd6a366ea1f985839c566cd61525ae/tomli-2.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c22a8bf253bacc0cf11f35ad9808b6cb75ada2631c2d97c971122583b129afbc", size = 241925, upload-time = "2025-10-08T22:01:29.066Z" },
+ { url = "https://files.pythonhosted.org/packages/70/91/7cdab9a03e6d3d2bb11beae108da5bdc1c34bdeb06e21163482544ddcc90/tomli-2.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0eea8cc5c5e9f89c9b90c4896a8deefc74f518db5927d0e0e8d4a80953d774d0", size = 249045, upload-time = "2025-10-08T22:01:31.98Z" },
+ { url = "https://files.pythonhosted.org/packages/15/1b/8c26874ed1f6e4f1fcfeb868db8a794cbe9f227299402db58cfcc858766c/tomli-2.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b74a0e59ec5d15127acdabd75ea17726ac4c5178ae51b85bfe39c4f8a278e879", size = 245835, upload-time = "2025-10-08T22:01:32.989Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/42/8e3c6a9a4b1a1360c1a2a39f0b972cef2cc9ebd56025168c4137192a9321/tomli-2.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b5870b50c9db823c595983571d1296a6ff3e1b88f734a4c8f6fc6188397de005", size = 253109, upload-time = "2025-10-08T22:01:34.052Z" },
+ { url = "https://files.pythonhosted.org/packages/22/0c/b4da635000a71b5f80130937eeac12e686eefb376b8dee113b4a582bba42/tomli-2.3.0-cp314-cp314-win32.whl", hash = "sha256:feb0dacc61170ed7ab602d3d972a58f14ee3ee60494292d384649a3dc38ef463", size = 97930, upload-time = "2025-10-08T22:01:35.082Z" },
+ { url = "https://files.pythonhosted.org/packages/b9/74/cb1abc870a418ae99cd5c9547d6bce30701a954e0e721821df483ef7223c/tomli-2.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:b273fcbd7fc64dc3600c098e39136522650c49bca95df2d11cf3b626422392c8", size = 107964, upload-time = "2025-10-08T22:01:36.057Z" },
+ { url = "https://files.pythonhosted.org/packages/54/78/5c46fff6432a712af9f792944f4fcd7067d8823157949f4e40c56b8b3c83/tomli-2.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:940d56ee0410fa17ee1f12b817b37a4d4e4dc4d27340863cc67236c74f582e77", size = 163065, upload-time = "2025-10-08T22:01:37.27Z" },
+ { url = "https://files.pythonhosted.org/packages/39/67/f85d9bd23182f45eca8939cd2bc7050e1f90c41f4a2ecbbd5963a1d1c486/tomli-2.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f85209946d1fe94416debbb88d00eb92ce9cd5266775424ff81bc959e001acaf", size = 159088, upload-time = "2025-10-08T22:01:38.235Z" },
+ { url = "https://files.pythonhosted.org/packages/26/5a/4b546a0405b9cc0659b399f12b6adb750757baf04250b148d3c5059fc4eb/tomli-2.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a56212bdcce682e56b0aaf79e869ba5d15a6163f88d5451cbde388d48b13f530", size = 268193, upload-time = "2025-10-08T22:01:39.712Z" },
+ { url = "https://files.pythonhosted.org/packages/42/4f/2c12a72ae22cf7b59a7fe75b3465b7aba40ea9145d026ba41cb382075b0e/tomli-2.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5f3ffd1e098dfc032d4d3af5c0ac64f6d286d98bc148698356847b80fa4de1b", size = 275488, upload-time = "2025-10-08T22:01:40.773Z" },
+ { url = "https://files.pythonhosted.org/packages/92/04/a038d65dbe160c3aa5a624e93ad98111090f6804027d474ba9c37c8ae186/tomli-2.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5e01decd096b1530d97d5d85cb4dff4af2d8347bd35686654a004f8dea20fc67", size = 272669, upload-time = "2025-10-08T22:01:41.824Z" },
+ { url = "https://files.pythonhosted.org/packages/be/2f/8b7c60a9d1612a7cbc39ffcca4f21a73bf368a80fc25bccf8253e2563267/tomli-2.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8a35dd0e643bb2610f156cca8db95d213a90015c11fee76c946aa62b7ae7e02f", size = 279709, upload-time = "2025-10-08T22:01:43.177Z" },
+ { url = "https://files.pythonhosted.org/packages/7e/46/cc36c679f09f27ded940281c38607716c86cf8ba4a518d524e349c8b4874/tomli-2.3.0-cp314-cp314t-win32.whl", hash = "sha256:a1f7f282fe248311650081faafa5f4732bdbfef5d45fe3f2e702fbc6f2d496e0", size = 107563, upload-time = "2025-10-08T22:01:44.233Z" },
+ { url = "https://files.pythonhosted.org/packages/84/ff/426ca8683cf7b753614480484f6437f568fd2fda2edbdf57a2d3d8b27a0b/tomli-2.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:70a251f8d4ba2d9ac2542eecf008b3c8a9fc5c3f9f02c56a9d7952612be2fdba", size = 119756, upload-time = "2025-10-08T22:01:45.234Z" },
+ { url = "https://files.pythonhosted.org/packages/77/b8/0135fadc89e73be292b473cb820b4f5a08197779206b33191e801feeae40/tomli-2.3.0-py3-none-any.whl", hash = "sha256:e95b1af3c5b07d9e643909b5abbec77cd9f1217e6d0bca72b0234736b9fb1f1b", size = 14408, upload-time = "2025-10-08T22:01:46.04Z" },
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.15.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
+]
+
+[[package]]
+name = "tzdata"
+version = "2025.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" },
+]
+
+[[package]]
+name = "uri-template"
+version = "1.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" },
+]
+
+[[package]]
+name = "webcolors"
+version = "24.11.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064, upload-time = "2024-11-11T07:43:24.224Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934, upload-time = "2024-11-11T07:43:22.529Z" },
+]
diff --git a/util/unicode/main.cpp b/util/unicode/main.cpp
index 1f31febeaaf..f83e575d4c3 100644
--- a/util/unicode/main.cpp
+++ b/util/unicode/main.cpp
@@ -16,8 +16,10 @@
#include <private/qunicodetables_p.h>
#endif
+#include <array>
#include <QtCore/qxpfunctional.h>
#include <QtCore/q26numeric.h>
+#include <vector>
#if QT_VERSION < QT_VERSION_CHECK(6, 9, 0)
// QSpan, QIODevice::readLineInto()
@@ -1018,13 +1020,14 @@ static const char *property_string =
" ushort unicodeVersion : 5; /* 5 used */\n"
" ushort eastAsianWidth : 3; /* 3 used */\n"
" ushort nfQuickCheck : 8;\n" // could be narrowed
- " std::array<CaseConversion, NumCases> cases;\n"
+ " ushort caseIndex : 16; /* 9 used */\n"
" ushort graphemeBreakClass : 5; /* 5 used */\n"
" ushort wordBreakClass : 5; /* 5 used */\n"
" ushort lineBreakClass : 6; /* 6 used */\n"
" ushort sentenceBreakClass : 4; /* 4 used */\n"
" ushort idnaStatus : 4; /* 3 used */\n"
" ushort script : 8;\n"
+ " ushort reserved : 16; /* makes sizeof a nice round 16 bytes */\n"
"};\n\n"
"Q_DECL_CONST_FUNCTION\n"
"Q_CORE_EXPORT const Properties * QT_FASTCALL properties(char32_t ucs4) noexcept;\n"
@@ -1063,7 +1066,7 @@ static const char *methods =
"{ return eastAsianWidth(ch.unicode()); }\n"
"\n";
-static const int SizeOfPropertiesStruct = 20;
+static const int SizeOfPropertiesStruct = 16;
static const QByteArray sizeOfPropertiesStructCheck =
"static_assert(sizeof(Properties) == " + QByteArray::number(SizeOfPropertiesStruct) + ");\n\n";
@@ -1096,6 +1099,7 @@ struct PropertyFlags {
&& upperCaseSpecial == o.upperCaseSpecial
&& titleCaseSpecial == o.titleCaseSpecial
&& caseFoldSpecial == o.caseFoldSpecial
+ // caseIndex is _not_ part of equality
&& graphemeBreakClass == o.graphemeBreakClass
&& wordBreakClass == o.wordBreakClass
&& sentenceBreakClass == o.sentenceBreakClass
@@ -1129,6 +1133,7 @@ struct PropertyFlags {
bool upperCaseSpecial = 0;
bool titleCaseSpecial = 0;
bool caseFoldSpecial = 0;
+ int caseIndex = -1; // not part of equality; replaces {lower,upper,title,fold}CaseDiff
GraphemeBreakClass graphemeBreakClass = GraphemeBreak_Any;
WordBreakClass wordBreakClass = WordBreak_Any;
SentenceBreakClass sentenceBreakClass = SentenceBreak_Any;
@@ -1821,6 +1826,8 @@ static void readLineBreak()
loc.die("Unassigned line break class \"%.*s\"", qPrintableView(l[1]));
for (int codepoint = from; codepoint <= to; ++codepoint) {
+ if (QChar::isSurrogate(codepoint) && lb != LineBreak_SG)
+ loc.die("Surrogate with line-break class != SG, fix line-break detection in QUnicodeTools");
UnicodeData &d = UnicodeData::valueRef(codepoint);
d.p.lineBreakClass = lb;
}
@@ -2585,6 +2592,77 @@ static void computeUniqueProperties()
qDebug(" %" PRIdQSIZETYPE " unique unicode properties found", uniqueProperties.size());
}
+struct CaseConversion {
+ ushort special : 1;
+ signed short diff : 15;
+
+ friend bool operator==(CaseConversion lhs, CaseConversion rhs) noexcept
+ {
+ static_assert(std::has_unique_object_representations_v<CaseConversion>);
+ return std::memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
+ }
+};
+using CaseConversions = std::array<CaseConversion, 4>;
+
+static std::vector<CaseConversions>
+computeUniqueCaseConversions(QList<PropertyFlags> &l)
+{
+ std::vector<CaseConversions> result;
+ result.emplace_back(); // all zeros should be at the beginning
+
+ qDebug("computeUniqueCaseConversions:");
+
+ size_t nonNullDuplicates = 0;
+
+ for (auto &e : l) {
+ CaseConversions candidate = {
+ CaseConversion{ e.lowerCaseSpecial, short(e.lowerCaseDiff) },
+ CaseConversion{ e.upperCaseSpecial, short(e.upperCaseDiff) },
+ CaseConversion{ e.titleCaseSpecial, short(e.titleCaseDiff) },
+ CaseConversion{ e.caseFoldSpecial, short(e.caseFoldDiff) },
+ };
+ const auto it = std::find(result.begin(), result.end(), candidate);
+ if (it == result.end()) {
+ // new one, add:
+ e.caseIndex = int(result.size());
+ result.push_back(std::move(candidate));
+ } else {
+ e.caseIndex = it - result.begin();
+ if (e.caseIndex != 0)
+ ++nonNullDuplicates;
+ }
+ }
+
+ qDebug(" %llu unique case conversions found (with %llu non-null duplicates)",
+ qulonglong(result.size()),
+ qulonglong(nonNullDuplicates));
+
+ return result;
+}
+
+static QByteArray createCaseConversions(std::vector<CaseConversions> conv)
+{
+ QByteArray out;
+
+ qDebug("createCaseConversions:");
+
+ out += "static constexpr std::array<CaseConversion, NumCases> caseConversions[] = {\n";
+ for (const auto &e : conv) {
+ out += " { { ";
+ for (const auto &f : e) {
+ out += "{ ";
+ out += QByteArray::number(f.special);
+ out += ", ";
+ out += QByteArray::number(f.diff);
+ out += " }, ";
+ }
+ out.chop(2); // removes ", "
+ out += " } },\n";
+ }
+ out += "};\n\n";
+ return out;
+}
+
struct UniqueBlock {
inline UniqueBlock() : index(-1) {}
@@ -2773,24 +2851,9 @@ static QByteArray createPropertyInfo()
// " ushort nfQuickCheck : 8;\n"
out += QByteArray::number( p.nfQuickCheck );
out += ", ";
-// " std::array<CaseConversion, NumCases> cases;\n"
- out += "{ { { ";
- out += QByteArray::number( p.lowerCaseSpecial );
- out += ", ";
- out += QByteArray::number( p.lowerCaseDiff );
- out += "}, {";
- out += QByteArray::number( p.upperCaseSpecial );
- out += ", ";
- out += QByteArray::number( p.upperCaseDiff );
- out += "}, {";
- out += QByteArray::number( p.titleCaseSpecial );
+// " ushort caseIndex; /* 9 used */\n"
+ out += QByteArray::number(p.caseIndex);
out += ", ";
- out += QByteArray::number( p.titleCaseDiff );
- out += "}, {";
- out += QByteArray::number( p.caseFoldSpecial );
- out += ", ";
- out += QByteArray::number( p.caseFoldDiff );
- out += "} } }, ";
// " ushort graphemeBreakClass : 5; /* 5 used */\n"
// " ushort wordBreakClass : 5; /* 5 used */\n"
// " ushort lineBreakClass : 6; /* 6 used */\n"
@@ -2808,6 +2871,9 @@ static QByteArray createPropertyInfo()
out += ", ";
// " ushort script : 8;\n"
out += QByteArray::number( p.script );
+ out += ", ";
+// " ushort reserved;\n"
+ out += '0';
out += " },";
}
if (out.endsWith(','))
@@ -2838,7 +2904,7 @@ static QByteArray createPropertyInfo()
"\n"
"QSpan<const CaseConversion, NumCases> QT_FASTCALL caseConversion(char32_t ucs4) noexcept\n"
"{\n"
- " return qGetProp(ucs4)->cases;\n"
+ " return caseConversions[qGetProp(ucs4)->caseIndex];\n"
"}\n\n";
out += "Q_CORE_EXPORT GraphemeBreakClass QT_FASTCALL graphemeBreakClass(char32_t ucs4) noexcept\n"
@@ -3358,6 +3424,8 @@ int main(int, char **)
resolveIdnaStatus();
computeUniqueProperties();
+
+ const QByteArray caseConv = createCaseConversions(computeUniqueCaseConversions(uniqueProperties));
QByteArray properties = createPropertyInfo();
QByteArray specialCases = createSpecialCaseMap();
QByteArray compositions = createCompositionInfo();
@@ -3365,13 +3433,13 @@ int main(int, char **)
QByteArray normalizationCorrections = createNormalizationCorrections();
QByteArray idnaMapping = createIdnaMapping();
- # REUSE-IgnoreStart
+ // REUSE-IgnoreStart
QByteArray header =
"// Copyright (C) 2020 The Qt Company Ltd.\n"
"// SPDX-License-Identifier: Unicode-3.0\n"
"// Qt-Security score:significant reason:default\n"
"\n";
- # REUSE-IgnoreEnd
+ // REUSE-IgnoreEnd
QByteArray note =
"/* This file is autogenerated from the Unicode " DATA_VERSION_S " database. Do not edit */\n\n";
@@ -3396,6 +3464,7 @@ int main(int, char **)
f.write("#include \"qunicodetables_p.h\"\n\n");
f.write("QT_BEGIN_NAMESPACE\n\n");
f.write("namespace QUnicodeTables {\n");
+ f.write(caseConv.data());
f.write(properties);
f.write(specialCases);
f.write(compositions);
diff --git a/util/xkbdatagen/main.cpp b/util/xkbdatagen/main.cpp
index 4c9227816b1..df0a1be7dbd 100644
--- a/util/xkbdatagen/main.cpp
+++ b/util/xkbdatagen/main.cpp
@@ -374,14 +374,14 @@ int main(int argc, char **argv)
}
QList<XKBLayout> layouts = findLayouts(layoutList);
- # REUSE-IgnoreStart
+ // REUSE-IgnoreStart
// copyright and stuff
printf("// Copyright (C) 2016 The Qt Company Ltd.\n"
"// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only\n"
"// This file is auto-generated, do not edit!\n"
"// (Generated using util/xkbdatagen)\n"
"\n");
- # REUSE-IgnoreEnd
+ // REUSE-IgnoreEnd
// data structure
printf("static struct {\n"