From 7a4e466ac655117d24400dc17f817a4ed6e7c9ca Mon Sep 17 00:00:00 2001 From: Joshua Leahy Date: Wed, 17 Sep 2025 15:20:27 +0000 Subject: [PATCH] Make TernFS open source --- .gitattributes | 4 + .github/workflows/main.yml | 4 + .gitignore | 4 + .vscode/settings.json.license | 3 + LICENSES/Apache-2.0.txt | 73 ++++++++++++++ LICENSES/GPL-2.0-or-later.txt | 117 ++++++++++++++++++++++ LICENSES/LLVM-exception.txt | 15 +++ LICENSES/MIT.txt | 18 ++++ README.md | 13 ++- build.sh | 5 + ci.py | 5 + common.py | 6 +- cpp/.gitignore | 4 + cpp/CMakeLists.txt | 4 + cpp/Dockerfile-alpine | 4 + cpp/Dockerfile-ubuntu | 6 +- cpp/build.py | 5 + cpp/cdc/CDC.cpp | 4 + cpp/cdc/CDC.hpp | 4 + cpp/cdc/CDCDB.cpp | 4 + cpp/cdc/CDCDB.hpp | 4 + cpp/cdc/CDCDBData.hpp | 4 + cpp/cdc/CMakeLists.txt | 4 + cpp/cdc/terncdc.cpp | 4 + cpp/core/Assert.hpp | 4 + cpp/core/AssertiveLock.hpp | 4 + cpp/core/BinaryFormatter.hpp | 4 + cpp/core/Bincode.cpp | 4 + cpp/core/Bincode.hpp | 4 + cpp/core/CDCKey.hpp | 4 + cpp/core/CMakeLists.txt | 4 + cpp/core/Common.cpp | 4 + cpp/core/Common.hpp | 4 + cpp/core/CommonOptions.cpp | 4 + cpp/core/CommonOptions.hpp | 4 + cpp/core/Connect.cpp | 4 + cpp/core/Connect.hpp | 4 + cpp/core/Crypto.cpp | 4 + cpp/core/Crypto.hpp | 4 + cpp/core/Env.cpp | 4 + cpp/core/Env.hpp | 4 + cpp/core/ErrorCount.cpp | 4 + cpp/core/ErrorCount.hpp | 4 + cpp/core/Exception.cpp | 4 + cpp/core/Exception.hpp | 4 + cpp/core/FormatTuple.cpp | 4 + cpp/core/FormatTuple.hpp | 4 + cpp/core/LogsDB.cpp | 4 + cpp/core/LogsDB.hpp | 4 + cpp/core/LogsDBData.hpp | 4 + cpp/core/Loop.cpp | 4 + cpp/core/Loop.hpp | 4 + cpp/core/Metrics.cpp | 4 + cpp/core/Metrics.hpp | 4 + cpp/core/Msgs.cpp | 4 + cpp/core/Msgs.hpp | 4 + cpp/core/MsgsGen.cpp | 4 + cpp/core/MsgsGen.hpp | 4 + cpp/core/MultiplexedChannel.hpp | 4 + cpp/core/PeriodicLoop.hpp | 4 + cpp/core/Protocol.hpp | 4 + cpp/core/Random.cpp | 1 + cpp/core/RegistryClient.cpp | 3 + cpp/core/RegistryClient.hpp | 4 + cpp/core/RocksDBUtils.cpp | 4 + cpp/core/RocksDBUtils.hpp | 4 + cpp/core/SPSC.hpp | 4 + cpp/core/SharedRocksDB.cpp | 4 + cpp/core/SharedRocksDB.hpp | 4 + cpp/core/Time.cpp | 4 + cpp/core/Time.hpp | 4 + cpp/core/Timings.cpp | 4 + cpp/core/Timings.hpp | 4 + cpp/core/UDPSocketPair.cpp | 4 + cpp/core/UDPSocketPair.hpp | 4 + cpp/core/Xmon.cpp | 3 + cpp/core/Xmon.hpp | 4 + cpp/core/XmonAgent.cpp | 4 + cpp/core/XmonAgent.hpp | 4 + cpp/core/httplib.h | 4 +- cpp/core/strerror.cpp | 4 + cpp/core/strerror.h | 6 +- cpp/crc32c/CMakeLists.txt | 3 + cpp/crc32c/crc32c.c | 5 + cpp/crc32c/crc32c.h | 6 +- cpp/crc32c/crc32c.py | 4 + cpp/crc32c/iscsi.h | 4 + cpp/crc32c/iscsi.hpp | 4 + cpp/crc32c/tables.cpp | 6 +- cpp/crc32c/tests.cpp | 6 +- cpp/dbtools/CDCDBTools.cpp | 4 + cpp/dbtools/CDCDBTools.hpp | 4 + cpp/dbtools/CMakeLists.txt | 4 + cpp/dbtools/LogsDBTools.cpp | 4 + cpp/dbtools/LogsDBTools.hpp | 4 + cpp/dbtools/ShardDBTools.cpp | 4 + cpp/dbtools/ShardDBTools.hpp | 4 + cpp/dbtools/terndbtools.cpp | 4 + cpp/ktools/CMakeLists.txt | 4 + cpp/ktools/ternktools.cpp | 4 + cpp/registry/CMakeLists.txt | 4 + cpp/registry/Registerer.cpp | 4 + cpp/registry/Registerer.hpp | 6 +- cpp/registry/Registry.cpp | 4 + cpp/registry/Registry.hpp | 4 + cpp/registry/RegistryCommon.hpp | 4 + cpp/registry/RegistryDB.cpp | 4 + cpp/registry/RegistryDB.hpp | 4 + cpp/registry/RegistryDBData.hpp | 4 + cpp/registry/RegistryKey.hpp | 4 + cpp/registry/RegistryServer.cpp | 6 +- cpp/registry/RegistryServer.hpp | 6 +- cpp/registry/RegistryState.hpp | 4 + cpp/registry/ternregistry.cpp | 6 +- cpp/rs/CMakeLists.txt | 3 + cpp/rs/bench.cpp | 6 +- cpp/rs/gf_tables.c | 4 + cpp/rs/gf_tables.py | 9 ++ cpp/rs/rs.cpp | 6 +- cpp/rs/rs.h | 6 +- cpp/rs/rs_core.c | 4 + cpp/rs/tests.cpp | 6 +- cpp/shard/BlockServicesCacheDB.cpp | 4 + cpp/shard/BlockServicesCacheDB.hpp | 4 + cpp/shard/CMakeLists.txt | 4 + cpp/shard/Shard.cpp | 4 + cpp/shard/Shard.hpp | 4 + cpp/shard/ShardDB.cpp | 4 + cpp/shard/ShardDB.hpp | 4 + cpp/shard/ShardDBData.cpp | 4 + cpp/shard/ShardDBData.hpp | 4 + cpp/shard/ShardKey.hpp | 4 + cpp/shard/ternshard.cpp | 4 + cpp/tests.sh | 5 + cpp/tests/CMakeLists.txt | 4 + cpp/tests/doctest.h | 5 + cpp/tests/logsdbtests.cpp | 4 + cpp/tests/tests.cpp | 4 + cpp/tests/utils/TempLogsDB.hpp | 4 + cpp/thirdparty.cmake | 10 ++ cpp/ubsan-ignorelist | 6 +- cpp/valgrind-suppressions | 4 + docs/alerts.md | 6 ++ docs/disk-failure.md | 6 ++ docs/gc.md | 6 ++ docs/kmod-file-tracking.md | 6 ++ docs/parity.md | 6 ++ go/.gitignore | 4 + go/badblocks/badblocks.go | 4 + go/bincodegen/FetchedFullSpan.hpp.license | 3 + go/bincodegen/FetchedSpan.hpp.license | 3 + go/bincodegen/bincodegen.go | 24 +++++ go/bincodegen/msgs_bincode.go.header | 4 + go/build.py | 5 + go/cleanup/collectdirectories.go | 4 + go/cleanup/defrag.go | 4 + go/cleanup/destructfiles.go | 4 + go/cleanup/migrate.go | 4 + go/cleanup/policy.go | 4 + go/cleanup/policy_test.go | 4 + go/cleanup/scratch/scratch.go | 4 + go/cleanup/scrub.go | 4 + go/cleanup/zeroblockservicefiles.go | 4 + go/client/blocksconn_test.go | 4 + go/client/blocksreq.go | 4 + go/client/cdcreq.go | 4 + go/client/client.go | 4 + go/client/dirinfocache.go | 4 + go/client/dirinfocache_test.go | 4 + go/client/metadatareq.go | 4 + go/client/parwalk.go | 4 + go/client/registryreq.go | 4 + go/client/shardreq.go | 4 + go/client/span.go | 4 + go/client/waitregistry.go | 4 + go/core/assert/assert.go | 4 + go/core/bincode/bincode.go | 4 + go/core/bufpool/bufpool.go | 4 + go/core/cbcmac/cbcmac.go | 4 + go/core/cbcmac/cbcmac_test.go | 4 + go/core/certificate/blockscert.go | 4 + go/core/crc32c/crc32c.go | 4 + go/core/crc32c/crc32c_test.go | 4 + go/core/flags/ipv4addr.go | 4 + go/core/flags/stringsflag.go | 4 + go/core/log/hardwareevent.go | 4 + go/core/log/log.go | 4 + go/core/log/metrics.go | 4 + go/core/log/xmon.go | 4 + go/core/managedprocess/managedprocess.go | 4 + go/core/managedroutine/managedroutine.go | 4 + go/core/parity/parity.go | 4 + go/core/recover/recover.go | 4 + go/core/rs/rs.go | 4 + go/core/rs/rs_test.go | 4 + go/core/timing/histogram.go | 4 + go/core/timing/ratelimit.go | 4 + go/core/timing/timeouts.go | 4 + go/core/timing/timings.go | 4 + go/core/timing/timings_test.go | 4 + go/core/wyhash/wyhash.go | 4 + go/crc32csum/crc32csum.go | 4 + go/msgs/msgs.go | 4 + go/msgs/msgs_bincode.go | 4 + go/msgs/public/public.go | 4 + go/s3/s3.go | 4 + go/ternblocks/ternblocks.go | 4 + go/terncli/filesamples/filesamples.go | 4 + go/terncli/kernelmetrics.go | 4 + go/terncli/terncli.go | 4 + go/ternfuse/ternfuse.go | 4 + go/terngc/terngc.go | 4 + go/ternregistryproxy/ternregistryproxy.go | 4 + go/ternrun/ternrun.go | 4 + go/terns3/terns3.go | 4 + go/terntests/cleanup.go | 4 + go/terntests/dirseek.go | 4 + go/terntests/filehistory.go | 4 + go/terntests/fstest.go | 4 + go/terntests/largefile.go | 4 + go/terntests/paralleldirs.go | 4 + go/terntests/preaddir.go | 4 + go/terntests/req.go | 4 + go/terntests/rsynctest.go | 4 + go/terntests/terntests.go | 4 + go/ternweb/base.html | 6 ++ go/ternweb/bootstrap.5.0.2.min.css | 4 +- go/ternweb/directory.html | 6 ++ go/ternweb/error.html | 6 ++ go/ternweb/file.html | 6 ++ go/ternweb/index.html | 6 ++ go/ternweb/preact-10.18.1.module.js | 4 + go/ternweb/preact-hooks-10.18.1.module.js | 4 + go/ternweb/scripts.js | 4 + go/ternweb/ternfs.png.license | 3 + go/ternweb/ternweb.go | 12 ++- go/ternweb/transient.html | 6 ++ integration.py | 5 + kmod/.gitignore | 4 + kmod/BUILD.md | 6 ++ kmod/Makefile | 4 + kmod/bincode.c | 4 + kmod/bincode.h | 4 + kmod/bincode_tests.c | 4 + kmod/bincodegen.c | 7 ++ kmod/bincodegen.h | 4 + kmod/block.c | 4 + kmod/block.h | 4 + kmod/block_services.c | 4 + kmod/block_services.h | 4 + kmod/build.sh | 5 + kmod/ci.sh | 5 + kmod/ci_prepare.sh | 5 + kmod/counter.h | 4 + kmod/crc.c | 4 + kmod/crc.h | 4 + kmod/createimg.sh | 7 +- kmod/debugfs.c | 4 + kmod/debugfs.h | 4 + kmod/dentry.c | 4 + kmod/dentry.h | 4 + kmod/dir.c | 4 + kmod/dir.h | 4 + kmod/err.c | 4 + kmod/err.h | 4 + kmod/export.c | 4 + kmod/export.h | 4 + kmod/fetchlinux.sh | 5 + kmod/file.c | 4 + kmod/file.h | 4 + kmod/gen_compile_commands.sh | 5 + kmod/inode.c | 4 + kmod/inode.h | 4 + kmod/inode_compat.h | 4 + kmod/intrshims.h | 4 + kmod/kmod.c | 4 + kmod/latch.h | 4 + kmod/log.h | 4 + kmod/metadata.c | 4 + kmod/metadata.h | 4 + kmod/net.c | 4 + kmod/net.h | 4 + kmod/net_compat.h | 4 + kmod/policy.c | 4 + kmod/policy.h | 4 + kmod/registry.c | 4 + kmod/registry.h | 4 + kmod/restartsession.sh | 4 + kmod/rs.c | 4 + kmod/rs.h | 4 + kmod/span.c | 4 + kmod/span.h | 4 + kmod/startvm.sh | 5 + kmod/super.c | 4 + kmod/super.h | 4 + kmod/sync.sh | 5 + kmod/sysctl.c | 4 + kmod/sysctl.h | 4 + kmod/sysfs.c | 4 + kmod/sysfs.h | 4 + kmod/trace.c | 4 + kmod/trace.h | 4 + kmod/vm_deploy.py | 7 +- kmod/wq.h | 4 + 304 files changed, 1512 insertions(+), 26 deletions(-) create mode 100644 .vscode/settings.json.license create mode 100644 LICENSES/Apache-2.0.txt create mode 100644 LICENSES/GPL-2.0-or-later.txt create mode 100644 LICENSES/LLVM-exception.txt create mode 100644 LICENSES/MIT.txt create mode 100644 go/bincodegen/FetchedFullSpan.hpp.license create mode 100644 go/bincodegen/FetchedSpan.hpp.license create mode 100644 go/ternweb/ternfs.png.license diff --git a/.gitattributes b/.gitattributes index 4d5bf93f..3a6a6fef 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + cpp/core/MsgsGen.cpp linguist-generated=true cpp/core/MsgsGen.hpp linguist-generated=true go/msgs/msgs_bincode.go linguist-generated=true diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 40ef01a8..226af50c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + name: CI on EC2 Runner on: diff --git a/.gitignore b/.gitignore index 67e44926..0163939c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + __pycache__/ .mypy_cache/ .cache/ diff --git a/.vscode/settings.json.license b/.vscode/settings.json.license new file mode 100644 index 00000000..2dbd9090 --- /dev/null +++ b/.vscode/settings.json.license @@ -0,0 +1,3 @@ +Copyright 2025 XTX Markets Technologies Limited + +SPDX-License-Identifier: GPL-2.0-or-later diff --git a/LICENSES/Apache-2.0.txt b/LICENSES/Apache-2.0.txt new file mode 100644 index 00000000..137069b8 --- /dev/null +++ b/LICENSES/Apache-2.0.txt @@ -0,0 +1,73 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + + You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + +To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/LICENSES/GPL-2.0-or-later.txt b/LICENSES/GPL-2.0-or-later.txt new file mode 100644 index 00000000..17cb2864 --- /dev/null +++ b/LICENSES/GPL-2.0-or-later.txt @@ -0,0 +1,117 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice diff --git a/LICENSES/LLVM-exception.txt b/LICENSES/LLVM-exception.txt new file mode 100644 index 00000000..fa4b725a --- /dev/null +++ b/LICENSES/LLVM-exception.txt @@ -0,0 +1,15 @@ +---- LLVM Exceptions to the Apache 2.0 License ---- + + As an exception, if, as a result of your compiling your source code, portions + of this Software are embedded into an Object form of such source code, you + may redistribute such embedded portions in such Object form without complying + with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + + In addition, if you combine or link compiled forms of this Software with + software that is licensed under the GPLv2 ("Combined Software") and if a + court of competent jurisdiction determines that the patent provision (Section + 3), the indemnity provision (Section 9) or other Section of the License + conflicts with the conditions of the GPLv2, you may retroactively and + prospectively choose to deem waived or otherwise exclude such Section(s) of + the License, but only in their entirety and only with respect to the Combined + Software. diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 00000000..d817195d --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,18 @@ +MIT License + +Copyright (c) + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and +associated documentation files (the "Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the +following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT +LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO +EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index fa6b0b44..dc78607a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ -[![TernFS Logo](https://github.com/user-attachments/assets/2e895b48-1a61-4b9d-aad0-2fc03777e817 "TernFS Logo")](https://ternfs.com) + + +[![TernFS Logo](https://github.com/user-attachments/assets/2e895b48-1a61-4b9d-aad0-2fc03777e817 "TernFS Logo")](https://ternfs.com) A distributed file system. For a high-level description of TernFS, see [the TernFS blog post on the XTX Markets Tech Blog](https://xtxmarkets.com/tech/2025-ternfs). This document provides a more bare-bones overview and an introduction to the codebase. @@ -215,3 +220,9 @@ Most of the codebase is understandable by VS Code/LSP: ## A note on naming TernFS was originally called EggsFS internally. This name quickly proved to be very poor due to the phonetic similarity to XFS, another notable filesystem. Therefore the filesystem was renamed to TernFS before open sourcing. However the old name lingers on in certain areas of the system that would have been hard to change, such as metric names. + +## Licensing + +TernFS is [Free Software](https://www.gnu.org/philosophy/free-sw.en.html). The default license for TernFS is [GPL-2.0-or-later](LICENSE/GPL-2.0-or-later.txt). + +The protocol definitions (`go/msgs/`), protocol generator (`go/bincodegen/`) and client library (`go/client/`, `go/core/`) are licensed under [Apache-2.0](LICENSES/Apache-2.0.txt) with the [LLVM-exception](LICENSES/LLVM-exception.txt). This license combination is both permissive (similar to MIT or BSD licenses) as well as compatible with both GPL license. We have done this to allow people to build their own proprietary client libraries while ensuring we can also freely incorporate them into the GPL v2 licensed Linux kernel. diff --git a/build.sh b/build.sh index b67a230f..a09393a8 100755 --- a/build.sh +++ b/build.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) diff --git a/ci.py b/ci.py index 8c1fe0b6..af79ed07 100755 --- a/ci.py +++ b/ci.py @@ -1,4 +1,9 @@ #!/usr/bin/env python3 + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + import os import argparse diff --git a/common.py b/common.py index be29f030..4f847f1f 100644 --- a/common.py +++ b/common.py @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + import sys import shlex import subprocess @@ -66,4 +70,4 @@ def run_cmd_unbuffered(*args, **kwargs): p.communicate() if p.returncode != 0: sys.exit(p.returncode) - return p \ No newline at end of file + return p diff --git a/cpp/.gitignore b/cpp/.gitignore index 2fe0b456..d1763043 100644 --- a/cpp/.gitignore +++ b/cpp/.gitignore @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + build/ compile_commands.json .cache/ diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 266a63d7..531c5f4d 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + cmake_minimum_required(VERSION 3.21) include(ExternalProject) diff --git a/cpp/Dockerfile-alpine b/cpp/Dockerfile-alpine index 5c69a1c0..1ee107ba 100644 --- a/cpp/Dockerfile-alpine +++ b/cpp/Dockerfile-alpine @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + # The image we use to build the static "alpine" binaries # that we deploy. # We are staying on 3.18 and patching in go1.22 instead of moving to 3.20 diff --git a/cpp/Dockerfile-ubuntu b/cpp/Dockerfile-ubuntu index f93597f3..0ab45501 100644 --- a/cpp/Dockerfile-ubuntu +++ b/cpp/Dockerfile-ubuntu @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + FROM ubuntu:22.04 LABEL org.opencontainers.image.source https://github.com/XTXMarkets/ternfs RUN set -eu @@ -12,4 +16,4 @@ RUN wget https://go.dev/dl/go1.22.3.linux-amd64.tar.gz RUN echo 8920ea521bad8f6b7bc377b4824982e011c19af27df88a815e3586ea895f1b36 go1.22.3.linux-amd64.tar.gz | sha256sum --check RUN tar -C /usr/local -xzf go1.22.3.linux-amd64.tar.gz; rm go1.22.3.linux-amd64.tar.gz ENV PATH="${PATH}:/usr/local/go/bin" -ENV IN_TERN_BUILD_CONTAINER Y \ No newline at end of file +ENV IN_TERN_BUILD_CONTAINER Y diff --git a/cpp/build.py b/cpp/build.py index 823f73f8..24d8c857 100755 --- a/cpp/build.py +++ b/cpp/build.py @@ -1,4 +1,9 @@ #!/usr/bin/env python3 + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + import sys import os from pathlib import Path diff --git a/cpp/cdc/CDC.cpp b/cpp/cdc/CDC.cpp index da255d1f..9f9d325d 100644 --- a/cpp/cdc/CDC.cpp +++ b/cpp/cdc/CDC.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/cpp/cdc/CDC.hpp b/cpp/cdc/CDC.hpp index 0302bed8..2ce3d3ff 100644 --- a/cpp/cdc/CDC.hpp +++ b/cpp/cdc/CDC.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include "CommonOptions.hpp" diff --git a/cpp/cdc/CDCDB.cpp b/cpp/cdc/CDCDB.cpp index 4a93a40d..3b64b497 100644 --- a/cpp/cdc/CDCDB.cpp +++ b/cpp/cdc/CDCDB.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "CDCDB.hpp" #include diff --git a/cpp/cdc/CDCDB.hpp b/cpp/cdc/CDCDB.hpp index 48989b12..f9f968cb 100644 --- a/cpp/cdc/CDCDB.hpp +++ b/cpp/cdc/CDCDB.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/cdc/CDCDBData.hpp b/cpp/cdc/CDCDBData.hpp index bbd642d9..028eb59e 100644 --- a/cpp/cdc/CDCDBData.hpp +++ b/cpp/cdc/CDCDBData.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/cdc/CMakeLists.txt b/cpp/cdc/CMakeLists.txt index 78edeebb..a483f7b3 100644 --- a/cpp/cdc/CMakeLists.txt +++ b/cpp/cdc/CMakeLists.txt @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + include_directories(${ternfs_SOURCE_DIR}/core ${ternfs_SOURCE_DIR}/shard) add_library(cdc CDC.cpp CDC.hpp CDCDB.cpp CDCDB.hpp CDCDBData.hpp) diff --git a/cpp/cdc/terncdc.cpp b/cpp/cdc/terncdc.cpp index 0b4bc854..b6d72b3b 100644 --- a/cpp/cdc/terncdc.cpp +++ b/cpp/cdc/terncdc.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include diff --git a/cpp/core/Assert.hpp b/cpp/core/Assert.hpp index 14e8e426..9b1d332d 100644 --- a/cpp/core/Assert.hpp +++ b/cpp/core/Assert.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "Common.hpp" diff --git a/cpp/core/AssertiveLock.hpp b/cpp/core/AssertiveLock.hpp index c7ecf165..41c8062f 100644 --- a/cpp/core/AssertiveLock.hpp +++ b/cpp/core/AssertiveLock.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/BinaryFormatter.hpp b/cpp/core/BinaryFormatter.hpp index d95ed951..a1284f1d 100644 --- a/cpp/core/BinaryFormatter.hpp +++ b/cpp/core/BinaryFormatter.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "Common.hpp" diff --git a/cpp/core/Bincode.cpp b/cpp/core/Bincode.cpp index 062f0429..c10935f0 100644 --- a/cpp/core/Bincode.cpp +++ b/cpp/core/Bincode.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "Bincode.hpp" #include "Common.hpp" diff --git a/cpp/core/Bincode.hpp b/cpp/core/Bincode.hpp index ebd38392..ef128fc0 100644 --- a/cpp/core/Bincode.hpp +++ b/cpp/core/Bincode.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/CDCKey.hpp b/cpp/core/CDCKey.hpp index d61ef652..607ef220 100644 --- a/cpp/core/CDCKey.hpp +++ b/cpp/core/CDCKey.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/CMakeLists.txt b/cpp/core/CMakeLists.txt index f0b67dbf..bedf4e57 100644 --- a/cpp/core/CMakeLists.txt +++ b/cpp/core/CMakeLists.txt @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + file(GLOB core_sources CONFIGURE_DEPENDS "*.cpp") file(GLOB core_headers CONFIGURE_DEPENDS "*.hpp") diff --git a/cpp/core/Common.cpp b/cpp/core/Common.cpp index 2798c6c3..2c028160 100644 --- a/cpp/core/Common.cpp +++ b/cpp/core/Common.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "Common.hpp" #include diff --git a/cpp/core/Common.hpp b/cpp/core/Common.hpp index f41c9791..a9121201 100644 --- a/cpp/core/Common.hpp +++ b/cpp/core/Common.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/CommonOptions.cpp b/cpp/core/CommonOptions.cpp index 646162c8..11e6f727 100644 --- a/cpp/core/CommonOptions.cpp +++ b/cpp/core/CommonOptions.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "CommonOptions.hpp" #include diff --git a/cpp/core/CommonOptions.hpp b/cpp/core/CommonOptions.hpp index 4ea55c5c..9e3286d6 100644 --- a/cpp/core/CommonOptions.hpp +++ b/cpp/core/CommonOptions.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "Env.hpp" diff --git a/cpp/core/Connect.cpp b/cpp/core/Connect.cpp index 7759bcb6..8201c215 100644 --- a/cpp/core/Connect.cpp +++ b/cpp/core/Connect.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include diff --git a/cpp/core/Connect.hpp b/cpp/core/Connect.hpp index 63c49d35..57c92b5a 100644 --- a/cpp/core/Connect.hpp +++ b/cpp/core/Connect.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Crypto.cpp b/cpp/core/Crypto.cpp index a9546583..5acc3e5e 100644 --- a/cpp/core/Crypto.cpp +++ b/cpp/core/Crypto.cpp @@ -1,3 +1,7 @@ +// Copyright 2016 Intel Corporation +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 #include #include diff --git a/cpp/core/Crypto.hpp b/cpp/core/Crypto.hpp index b1fbd3c2..d54ea085 100644 --- a/cpp/core/Crypto.hpp +++ b/cpp/core/Crypto.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Env.cpp b/cpp/core/Env.cpp index ffd4e1de..ce4fe709 100644 --- a/cpp/core/Env.cpp +++ b/cpp/core/Env.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include diff --git a/cpp/core/Env.hpp b/cpp/core/Env.hpp index 7259c19a..f57ff890 100644 --- a/cpp/core/Env.hpp +++ b/cpp/core/Env.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/ErrorCount.cpp b/cpp/core/ErrorCount.cpp index 82afb29e..b46fc409 100644 --- a/cpp/core/ErrorCount.cpp +++ b/cpp/core/ErrorCount.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "ErrorCount.hpp" void ErrorCount::reset() { diff --git a/cpp/core/ErrorCount.hpp b/cpp/core/ErrorCount.hpp index b046c7e5..62971d45 100644 --- a/cpp/core/ErrorCount.hpp +++ b/cpp/core/ErrorCount.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Exception.cpp b/cpp/core/Exception.cpp index 91e95a21..fe6f2e6e 100644 --- a/cpp/core/Exception.cpp +++ b/cpp/core/Exception.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include diff --git a/cpp/core/Exception.hpp b/cpp/core/Exception.hpp index 69ac7bad..44878c37 100644 --- a/cpp/core/Exception.hpp +++ b/cpp/core/Exception.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/FormatTuple.cpp b/cpp/core/FormatTuple.cpp index 280a82c1..a41bfd81 100644 --- a/cpp/core/FormatTuple.cpp +++ b/cpp/core/FormatTuple.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "FormatTuple.hpp" namespace ft_detail { diff --git a/cpp/core/FormatTuple.hpp b/cpp/core/FormatTuple.hpp index c9f05363..37454ae3 100644 --- a/cpp/core/FormatTuple.hpp +++ b/cpp/core/FormatTuple.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/LogsDB.cpp b/cpp/core/LogsDB.cpp index 6662f142..4498a829 100644 --- a/cpp/core/LogsDB.cpp +++ b/cpp/core/LogsDB.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "LogsDB.hpp" #include diff --git a/cpp/core/LogsDB.hpp b/cpp/core/LogsDB.hpp index a15118f7..cd49e1b4 100644 --- a/cpp/core/LogsDB.hpp +++ b/cpp/core/LogsDB.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/LogsDBData.hpp b/cpp/core/LogsDBData.hpp index cfc40f9e..34a11b5d 100644 --- a/cpp/core/LogsDBData.hpp +++ b/cpp/core/LogsDBData.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Loop.cpp b/cpp/core/Loop.cpp index 91382b8a..879ae313 100644 --- a/cpp/core/Loop.cpp +++ b/cpp/core/Loop.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include diff --git a/cpp/core/Loop.hpp b/cpp/core/Loop.hpp index 4ede340e..36329b19 100644 --- a/cpp/core/Loop.hpp +++ b/cpp/core/Loop.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Metrics.cpp b/cpp/core/Metrics.cpp index 84ce1d9c..9938699c 100644 --- a/cpp/core/Metrics.cpp +++ b/cpp/core/Metrics.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // See // for docs. #include "Metrics.hpp" diff --git a/cpp/core/Metrics.hpp b/cpp/core/Metrics.hpp index 922b3487..82d63502 100644 --- a/cpp/core/Metrics.hpp +++ b/cpp/core/Metrics.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "Time.hpp" diff --git a/cpp/core/Msgs.cpp b/cpp/core/Msgs.cpp index 11154e39..189faef6 100644 --- a/cpp/core/Msgs.cpp +++ b/cpp/core/Msgs.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "Msgs.hpp" #include diff --git a/cpp/core/Msgs.hpp b/cpp/core/Msgs.hpp index 5be9c8d0..c46d0c0d 100644 --- a/cpp/core/Msgs.hpp +++ b/cpp/core/Msgs.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/MsgsGen.cpp b/cpp/core/MsgsGen.cpp index 06756723..336ecd17 100644 --- a/cpp/core/MsgsGen.cpp +++ b/cpp/core/MsgsGen.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Automatically generated with go run bincodegen. // Run `go generate ./...` from the go/ directory to regenerate it. #include "MsgsGen.hpp" diff --git a/cpp/core/MsgsGen.hpp b/cpp/core/MsgsGen.hpp index 93c1028c..370335ec 100644 --- a/cpp/core/MsgsGen.hpp +++ b/cpp/core/MsgsGen.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Automatically generated with go run bincodegen. // Run `go generate ./...` from the go/ directory to regenerate it. #pragma once diff --git a/cpp/core/MultiplexedChannel.hpp b/cpp/core/MultiplexedChannel.hpp index 0e29d76c..79ca6f64 100644 --- a/cpp/core/MultiplexedChannel.hpp +++ b/cpp/core/MultiplexedChannel.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/PeriodicLoop.hpp b/cpp/core/PeriodicLoop.hpp index a1915da6..d17a23a2 100644 --- a/cpp/core/PeriodicLoop.hpp +++ b/cpp/core/PeriodicLoop.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "Exception.hpp" diff --git a/cpp/core/Protocol.hpp b/cpp/core/Protocol.hpp index d453793a..95696ac9 100644 --- a/cpp/core/Protocol.hpp +++ b/cpp/core/Protocol.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "MsgsGen.hpp" diff --git a/cpp/core/Random.cpp b/cpp/core/Random.cpp index 4bef5d52..2a33f213 100644 --- a/cpp/core/Random.cpp +++ b/cpp/core/Random.cpp @@ -1,3 +1,4 @@ +// Copyright 2023 Peter Cawley // Copyright 2025 XTX Markets Technologies Limited // // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception diff --git a/cpp/core/RegistryClient.cpp b/cpp/core/RegistryClient.cpp index 4a20f0dc..d30a8667 100644 --- a/cpp/core/RegistryClient.cpp +++ b/cpp/core/RegistryClient.cpp @@ -1,3 +1,6 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include #include diff --git a/cpp/core/RegistryClient.hpp b/cpp/core/RegistryClient.hpp index 191a051d..69ead93d 100644 --- a/cpp/core/RegistryClient.hpp +++ b/cpp/core/RegistryClient.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "Msgs.hpp" diff --git a/cpp/core/RocksDBUtils.cpp b/cpp/core/RocksDBUtils.cpp index 4db03dc7..06886f23 100644 --- a/cpp/core/RocksDBUtils.cpp +++ b/cpp/core/RocksDBUtils.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include diff --git a/cpp/core/RocksDBUtils.hpp b/cpp/core/RocksDBUtils.hpp index 106d3fcf..c118f439 100644 --- a/cpp/core/RocksDBUtils.hpp +++ b/cpp/core/RocksDBUtils.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/SPSC.hpp b/cpp/core/SPSC.hpp index ba47f25f..2d452258 100644 --- a/cpp/core/SPSC.hpp +++ b/cpp/core/SPSC.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/SharedRocksDB.cpp b/cpp/core/SharedRocksDB.cpp index 656c959f..6841d98f 100644 --- a/cpp/core/SharedRocksDB.cpp +++ b/cpp/core/SharedRocksDB.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "SharedRocksDB.hpp" #include diff --git a/cpp/core/SharedRocksDB.hpp b/cpp/core/SharedRocksDB.hpp index 82d67960..5baa66b0 100644 --- a/cpp/core/SharedRocksDB.hpp +++ b/cpp/core/SharedRocksDB.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Time.cpp b/cpp/core/Time.cpp index d4463071..8d5a3579 100644 --- a/cpp/core/Time.cpp +++ b/cpp/core/Time.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include diff --git a/cpp/core/Time.hpp b/cpp/core/Time.hpp index 73d902e1..a8347f73 100644 --- a/cpp/core/Time.hpp +++ b/cpp/core/Time.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Timings.cpp b/cpp/core/Timings.cpp index e0cf6467..70d31030 100644 --- a/cpp/core/Timings.cpp +++ b/cpp/core/Timings.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "Timings.hpp" Timings::Timings(Duration firstUpperBound, double growth, int bins) : diff --git a/cpp/core/Timings.hpp b/cpp/core/Timings.hpp index bc17d27c..91913b1a 100644 --- a/cpp/core/Timings.hpp +++ b/cpp/core/Timings.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/UDPSocketPair.cpp b/cpp/core/UDPSocketPair.cpp index 4b201991..5ca383b4 100644 --- a/cpp/core/UDPSocketPair.cpp +++ b/cpp/core/UDPSocketPair.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "UDPSocketPair.hpp" #include "Common.hpp" diff --git a/cpp/core/UDPSocketPair.hpp b/cpp/core/UDPSocketPair.hpp index eafa0191..810295c0 100644 --- a/cpp/core/UDPSocketPair.hpp +++ b/cpp/core/UDPSocketPair.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/Xmon.cpp b/cpp/core/Xmon.cpp index 15b1417b..c35be534 100644 --- a/cpp/core/Xmon.cpp +++ b/cpp/core/Xmon.cpp @@ -1,3 +1,6 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include #include diff --git a/cpp/core/Xmon.hpp b/cpp/core/Xmon.hpp index c188a14f..5acea938 100644 --- a/cpp/core/Xmon.hpp +++ b/cpp/core/Xmon.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/core/XmonAgent.cpp b/cpp/core/XmonAgent.cpp index 74a4730d..77be4f72 100644 --- a/cpp/core/XmonAgent.cpp +++ b/cpp/core/XmonAgent.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include "XmonAgent.hpp" #include "Assert.hpp" diff --git a/cpp/core/XmonAgent.hpp b/cpp/core/XmonAgent.hpp index d7c0221c..c5c9514e 100644 --- a/cpp/core/XmonAgent.hpp +++ b/cpp/core/XmonAgent.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include "Time.hpp" diff --git a/cpp/core/httplib.h b/cpp/core/httplib.h index 3c608f8d..28dbd00b 100644 --- a/cpp/core/httplib.h +++ b/cpp/core/httplib.h @@ -3,8 +3,8 @@ // // httplib.h // -// Copyright (c) 2023 Yuji Hirose. All rights reserved. -// MIT License +// Copyright (c) 2017 yhirose +// SPDX-License-Identifier: MIT // #ifndef CPPHTTPLIB_HTTPLIB_H diff --git a/cpp/core/strerror.cpp b/cpp/core/strerror.cpp index 1bbea812..34ad52a7 100644 --- a/cpp/core/strerror.cpp +++ b/cpp/core/strerror.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include diff --git a/cpp/core/strerror.h b/cpp/core/strerror.h index 8b3d980d..a426c00f 100644 --- a/cpp/core/strerror.h +++ b/cpp/core/strerror.h @@ -1 +1,5 @@ -const char* safe_strerror(int errnum); \ No newline at end of file +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +const char* safe_strerror(int errnum); diff --git a/cpp/crc32c/CMakeLists.txt b/cpp/crc32c/CMakeLists.txt index cb785625..e07c3126 100644 --- a/cpp/crc32c/CMakeLists.txt +++ b/cpp/crc32c/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception include_directories(${ternfs_SOURCE_DIR}/core) diff --git a/cpp/crc32c/crc32c.c b/cpp/crc32c/crc32c.c index 5ba00963..381f3173 100644 --- a/cpp/crc32c/crc32c.c +++ b/cpp/crc32c/crc32c.c @@ -1,3 +1,8 @@ +// Copyright 2022 Peter Cawley +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #ifndef __KERNEL__ #include "crc32c.h" diff --git a/cpp/crc32c/crc32c.h b/cpp/crc32c/crc32c.h index 4335d130..99c5faac 100644 --- a/cpp/crc32c/crc32c.h +++ b/cpp/crc32c/crc32c.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Computes the CRC32C (C = "Castagnoli" polynomial, also used in iSCSI) // // As usual, the CRC is initialized with -1, and xor'd with -1 at the end. @@ -40,4 +44,4 @@ uint32_t crc32c_zero_extend(uint32_t crc, ssize_t zeros); } #endif -#endif \ No newline at end of file +#endif diff --git a/cpp/crc32c/crc32c.py b/cpp/crc32c/crc32c.py index 388c779b..6ca0ce55 100644 --- a/cpp/crc32c/crc32c.py +++ b/cpp/crc32c/crc32c.py @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + # File to remind myself how to derive: # # * CRC32C(A ^ B) given CRC32C(A) and CRC32C(B) diff --git a/cpp/crc32c/iscsi.h b/cpp/crc32c/iscsi.h index 1a0d59f3..9496eb52 100644 --- a/cpp/crc32c/iscsi.h +++ b/cpp/crc32c/iscsi.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #define ISCSI_POLY 0x82F63B78u // Return a(x) multiplied by b(x) modulo ISCSI_POLY, For speed, this requires diff --git a/cpp/crc32c/iscsi.hpp b/cpp/crc32c/iscsi.hpp index 25077926..99ee9a04 100644 --- a/cpp/crc32c/iscsi.hpp +++ b/cpp/crc32c/iscsi.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #pragma once #include diff --git a/cpp/crc32c/tables.cpp b/cpp/crc32c/tables.cpp index b6053a27..7d588860 100644 --- a/cpp/crc32c/tables.cpp +++ b/cpp/crc32c/tables.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include @@ -38,4 +42,4 @@ int main() { p = crc32c_mult_mod_p(p, p); } printf("\n};\n\n"); -} \ No newline at end of file +} diff --git a/cpp/crc32c/tests.cpp b/cpp/crc32c/tests.cpp index d82865ce..9b8033ea 100644 --- a/cpp/crc32c/tests.cpp +++ b/cpp/crc32c/tests.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include @@ -92,4 +96,4 @@ int main() { } return 0; -} \ No newline at end of file +} diff --git a/cpp/dbtools/CDCDBTools.cpp b/cpp/dbtools/CDCDBTools.cpp index ba1af76e..f05fe5c2 100644 --- a/cpp/dbtools/CDCDBTools.cpp +++ b/cpp/dbtools/CDCDBTools.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "CDCDBTools.hpp" #include diff --git a/cpp/dbtools/CDCDBTools.hpp b/cpp/dbtools/CDCDBTools.hpp index ed389b74..3612855b 100644 --- a/cpp/dbtools/CDCDBTools.hpp +++ b/cpp/dbtools/CDCDBTools.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include "Msgs.hpp" diff --git a/cpp/dbtools/CMakeLists.txt b/cpp/dbtools/CMakeLists.txt index fc909632..b71775e2 100644 --- a/cpp/dbtools/CMakeLists.txt +++ b/cpp/dbtools/CMakeLists.txt @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + include_directories(${ternfs_SOURCE_DIR}/core ${ternfs_SOURCE_DIR}/shard ${ternfs_SOURCE_DIR}/cdc) add_library(sharddbtools ShardDBTools.hpp ShardDBTools.cpp LogsDBTools.hpp LogsDBTools.cpp CDCDBTools.hpp CDCDBTools.cpp) diff --git a/cpp/dbtools/LogsDBTools.cpp b/cpp/dbtools/LogsDBTools.cpp index a65126e2..43b49950 100644 --- a/cpp/dbtools/LogsDBTools.cpp +++ b/cpp/dbtools/LogsDBTools.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "LogsDBTools.hpp" #include diff --git a/cpp/dbtools/LogsDBTools.hpp b/cpp/dbtools/LogsDBTools.hpp index 6386a6ce..21e71fed 100644 --- a/cpp/dbtools/LogsDBTools.hpp +++ b/cpp/dbtools/LogsDBTools.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/dbtools/ShardDBTools.cpp b/cpp/dbtools/ShardDBTools.cpp index a32f57f4..fc7e4016 100644 --- a/cpp/dbtools/ShardDBTools.cpp +++ b/cpp/dbtools/ShardDBTools.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "ShardDBTools.hpp" #include diff --git a/cpp/dbtools/ShardDBTools.hpp b/cpp/dbtools/ShardDBTools.hpp index b9d4130f..06dbe213 100644 --- a/cpp/dbtools/ShardDBTools.hpp +++ b/cpp/dbtools/ShardDBTools.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include "Msgs.hpp" diff --git a/cpp/dbtools/terndbtools.cpp b/cpp/dbtools/terndbtools.cpp index 2cda320e..42b78505 100644 --- a/cpp/dbtools/terndbtools.cpp +++ b/cpp/dbtools/terndbtools.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/cpp/ktools/CMakeLists.txt b/cpp/ktools/CMakeLists.txt index 083eb27b..db43b7e0 100644 --- a/cpp/ktools/CMakeLists.txt +++ b/cpp/ktools/CMakeLists.txt @@ -1 +1,5 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + add_executable(ternktools ternktools.cpp) \ No newline at end of file diff --git a/cpp/ktools/ternktools.cpp b/cpp/ktools/ternktools.cpp index b73fe331..3c959e50 100644 --- a/cpp/ktools/ternktools.cpp +++ b/cpp/ktools/ternktools.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/cpp/registry/CMakeLists.txt b/cpp/registry/CMakeLists.txt index 63c61b78..24a9db88 100644 --- a/cpp/registry/CMakeLists.txt +++ b/cpp/registry/CMakeLists.txt @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + include_directories(${ternfs_SOURCE_DIR}/core ${ternfs_SOURCE_DIR}/wyhash) add_library(registry Registry.hpp Registry.cpp RegistryDB.hpp RegistryDB.cpp diff --git a/cpp/registry/Registerer.cpp b/cpp/registry/Registerer.cpp index 4c4ea689..207ee0dd 100644 --- a/cpp/registry/Registerer.cpp +++ b/cpp/registry/Registerer.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "Registerer.hpp" #include "LogsDB.hpp" #include diff --git a/cpp/registry/Registerer.hpp b/cpp/registry/Registerer.hpp index 6abe14c3..5efe0f2c 100644 --- a/cpp/registry/Registerer.hpp +++ b/cpp/registry/Registerer.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include @@ -45,4 +49,4 @@ private: void _init(const std::vector &cachedReplicas); bool _updateReplicas(const std::vector &allReplicas); -}; \ No newline at end of file +}; diff --git a/cpp/registry/Registry.cpp b/cpp/registry/Registry.cpp index 61c4601a..1e0862f9 100644 --- a/cpp/registry/Registry.cpp +++ b/cpp/registry/Registry.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/cpp/registry/Registry.hpp b/cpp/registry/Registry.hpp index 44371ba1..9ee5dde6 100644 --- a/cpp/registry/Registry.hpp +++ b/cpp/registry/Registry.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once diff --git a/cpp/registry/RegistryCommon.hpp b/cpp/registry/RegistryCommon.hpp index 7a88a754..54bc324d 100644 --- a/cpp/registry/RegistryCommon.hpp +++ b/cpp/registry/RegistryCommon.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/registry/RegistryDB.cpp b/cpp/registry/RegistryDB.cpp index 5ef0bde1..a3d3eef7 100644 --- a/cpp/registry/RegistryDB.cpp +++ b/cpp/registry/RegistryDB.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "RegistryDB.hpp" #include "Assert.hpp" #include "Bincode.hpp" diff --git a/cpp/registry/RegistryDB.hpp b/cpp/registry/RegistryDB.hpp index 9675692f..48e6b9d9 100644 --- a/cpp/registry/RegistryDB.hpp +++ b/cpp/registry/RegistryDB.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/registry/RegistryDBData.hpp b/cpp/registry/RegistryDBData.hpp index ea40f2fe..6da80cc7 100644 --- a/cpp/registry/RegistryDBData.hpp +++ b/cpp/registry/RegistryDBData.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/registry/RegistryKey.hpp b/cpp/registry/RegistryKey.hpp index ec4dc484..2f0f0893 100644 --- a/cpp/registry/RegistryKey.hpp +++ b/cpp/registry/RegistryKey.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/registry/RegistryServer.cpp b/cpp/registry/RegistryServer.cpp index d045e51e..d77e1bfa 100644 --- a/cpp/registry/RegistryServer.cpp +++ b/cpp/registry/RegistryServer.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "RegistryServer.hpp" #include "Assert.hpp" #include "Env.hpp" @@ -436,4 +440,4 @@ void RegistryServer::_packLogsDBRequest(LogsDBRequest &request) { }); LOG_TRACE(_env, "will send request for req id %s kind %s to %s", request.msg.id, request.msg.body.kind(), addrInfo); -} \ No newline at end of file +} diff --git a/cpp/registry/RegistryServer.hpp b/cpp/registry/RegistryServer.hpp index 79ecc590..9a8f98dc 100644 --- a/cpp/registry/RegistryServer.hpp +++ b/cpp/registry/RegistryServer.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include "LogsDB.hpp" @@ -123,4 +127,4 @@ private: void _packLogsDBResponse(LogsDBResponse &response); void _packLogsDBRequest(LogsDBRequest &request); -}; \ No newline at end of file +}; diff --git a/cpp/registry/RegistryState.hpp b/cpp/registry/RegistryState.hpp index b92bc326..31172d6e 100644 --- a/cpp/registry/RegistryState.hpp +++ b/cpp/registry/RegistryState.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/registry/ternregistry.cpp b/cpp/registry/ternregistry.cpp index db936f1c..cf0ec4e2 100644 --- a/cpp/registry/ternregistry.cpp +++ b/cpp/registry/ternregistry.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include @@ -156,4 +160,4 @@ int main(int argc, char** argv) { LOG_INFO(env, "registry stopped. Exiting"); return 0; -} \ No newline at end of file +} diff --git a/cpp/rs/CMakeLists.txt b/cpp/rs/CMakeLists.txt index 36843b97..2ccd4a76 100644 --- a/cpp/rs/CMakeLists.txt +++ b/cpp/rs/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception include_directories(${ternfs_SOURCE_DIR}/core) diff --git a/cpp/rs/bench.cpp b/cpp/rs/bench.cpp index 5ecfa08c..9b2da066 100644 --- a/cpp/rs/bench.cpp +++ b/cpp/rs/bench.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include @@ -67,4 +71,4 @@ int main(int argc, const char** argv) { printf("Recover (total memory touched): %0.2fGB/s\n", gbPerSecond); return 0; -} \ No newline at end of file +} diff --git a/cpp/rs/gf_tables.c b/cpp/rs/gf_tables.c index 7a883c33..bc235906 100644 --- a/cpp/rs/gf_tables.c +++ b/cpp/rs/gf_tables.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // generated with gf_tables.py #ifndef __KERNEL__ #include diff --git a/cpp/rs/gf_tables.py b/cpp/rs/gf_tables.py index 92647c59..6a9b172c 100644 --- a/cpp/rs/gf_tables.py +++ b/cpp/rs/gf_tables.py @@ -1,9 +1,18 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # Rijndael's poly, see POLY = 0x11B # x^8 + x^4 + x^3 + x + 1, or 100011011 # See GENERATOR = 0x03 # x + 1, or 00000011 +# REUSE-IgnoreStart +print('// Copyright 2025 XTX Markets Technologies Limited') +print('//') +print('// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception') +# REUSE-IgnoreEnd +print() print('// generated with gf_tables.py') print('#ifndef __KERNEL__') print('#include ') diff --git a/cpp/rs/rs.cpp b/cpp/rs/rs.cpp index f1e83e06..6923c8cd 100644 --- a/cpp/rs/rs.cpp +++ b/cpp/rs/rs.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include @@ -486,4 +490,4 @@ static void rs_initialize_recover_matmul_funcs() { rs_recover_matmul_funcs[13] = &rs_recover_matmul_tmpl<13>; rs_recover_matmul_funcs[14] = &rs_recover_matmul_tmpl<14>; rs_recover_matmul_funcs[15] = &rs_recover_matmul_tmpl<15>; -} \ No newline at end of file +} diff --git a/cpp/rs/rs.h b/cpp/rs/rs.h index 27cfda3d..95fc75f2 100644 --- a/cpp/rs/rs.h +++ b/cpp/rs/rs.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Reed-Solomon implementation in the style of // // @@ -92,4 +96,4 @@ void rs_recover( } #endif -#endif \ No newline at end of file +#endif diff --git a/cpp/rs/rs_core.c b/cpp/rs/rs_core.c index 960cdc9b..d46f00cc 100644 --- a/cpp/rs/rs_core.c +++ b/cpp/rs/rs_core.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #ifndef __KERNEL__ typedef uint8_t u8; diff --git a/cpp/rs/tests.cpp b/cpp/rs/tests.cpp index 1752da99..b4111db7 100644 --- a/cpp/rs/tests.cpp +++ b/cpp/rs/tests.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + #include #include #include @@ -77,4 +81,4 @@ int main() { } } return 0; -} \ No newline at end of file +} diff --git a/cpp/shard/BlockServicesCacheDB.cpp b/cpp/shard/BlockServicesCacheDB.cpp index ec95be9f..16efabb3 100644 --- a/cpp/shard/BlockServicesCacheDB.cpp +++ b/cpp/shard/BlockServicesCacheDB.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include diff --git a/cpp/shard/BlockServicesCacheDB.hpp b/cpp/shard/BlockServicesCacheDB.hpp index 72e1e774..4dc5997c 100644 --- a/cpp/shard/BlockServicesCacheDB.hpp +++ b/cpp/shard/BlockServicesCacheDB.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/shard/CMakeLists.txt b/cpp/shard/CMakeLists.txt index 7893fa3e..8bd7d6cc 100644 --- a/cpp/shard/CMakeLists.txt +++ b/cpp/shard/CMakeLists.txt @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + include_directories(${ternfs_SOURCE_DIR}/core ${ternfs_SOURCE_DIR}/crc32c) add_library(shard Shard.cpp Shard.hpp ShardDB.cpp ShardDB.hpp ShardDBData.cpp ShardDBData.hpp BlockServicesCacheDB.hpp BlockServicesCacheDB.cpp) diff --git a/cpp/shard/Shard.cpp b/cpp/shard/Shard.cpp index 9b2b7d4a..ae42e387 100644 --- a/cpp/shard/Shard.cpp +++ b/cpp/shard/Shard.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "Shard.hpp" #include diff --git a/cpp/shard/Shard.hpp b/cpp/shard/Shard.hpp index b589c8ca..575471a5 100644 --- a/cpp/shard/Shard.hpp +++ b/cpp/shard/Shard.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include "CommonOptions.hpp" diff --git a/cpp/shard/ShardDB.cpp b/cpp/shard/ShardDB.cpp index c6227088..97551d59 100644 --- a/cpp/shard/ShardDB.cpp +++ b/cpp/shard/ShardDB.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "ShardDB.hpp" #include diff --git a/cpp/shard/ShardDB.hpp b/cpp/shard/ShardDB.hpp index badf1279..72e9c532 100644 --- a/cpp/shard/ShardDB.hpp +++ b/cpp/shard/ShardDB.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/shard/ShardDBData.cpp b/cpp/shard/ShardDBData.cpp index 03a46ed8..722bae10 100644 --- a/cpp/shard/ShardDBData.cpp +++ b/cpp/shard/ShardDBData.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "ShardDBData.hpp" #include diff --git a/cpp/shard/ShardDBData.hpp b/cpp/shard/ShardDBData.hpp index c6b6f15f..5a5c6671 100644 --- a/cpp/shard/ShardDBData.hpp +++ b/cpp/shard/ShardDBData.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/shard/ShardKey.hpp b/cpp/shard/ShardKey.hpp index a446b57c..7210a919 100644 --- a/cpp/shard/ShardKey.hpp +++ b/cpp/shard/ShardKey.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/shard/ternshard.cpp b/cpp/shard/ternshard.cpp index f00986c8..5b16ede0 100644 --- a/cpp/shard/ternshard.cpp +++ b/cpp/shard/ternshard.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/cpp/tests.sh b/cpp/tests.sh index 3c397328..fb524f5e 100755 --- a/cpp/tests.sh +++ b/cpp/tests.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail cd "$(dirname "$0")" diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 717ccf99..e39496ba 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + include_directories(${ternfs_SOURCE_DIR}/core ${ternfs_SOURCE_DIR}/shard) add_executable(tests tests.cpp doctest.h) diff --git a/cpp/tests/doctest.h b/cpp/tests/doctest.h index 5cff86f2..ecddd9fd 100644 --- a/cpp/tests/doctest.h +++ b/cpp/tests/doctest.h @@ -1,3 +1,8 @@ +// Copyright (c) 2016-2023 Viktor Kirilov +// +// SPDX-License-Identifier: MIT +// + // Retrieved from // ====================================================================== lgtm [cpp/missing-header-guard] diff --git a/cpp/tests/logsdbtests.cpp b/cpp/tests/logsdbtests.cpp index 94b8e034..7f19bb80 100644 --- a/cpp/tests/logsdbtests.cpp +++ b/cpp/tests/logsdbtests.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/cpp/tests/tests.cpp b/cpp/tests/tests.cpp index ed147260..44b2863d 100644 --- a/cpp/tests/tests.cpp +++ b/cpp/tests/tests.cpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/cpp/tests/utils/TempLogsDB.hpp b/cpp/tests/utils/TempLogsDB.hpp index 003a8900..38e0a881 100644 --- a/cpp/tests/utils/TempLogsDB.hpp +++ b/cpp/tests/utils/TempLogsDB.hpp @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #pragma once #include diff --git a/cpp/thirdparty.cmake b/cpp/thirdparty.cmake index 226b198d..b957f686 100644 --- a/cpp/thirdparty.cmake +++ b/cpp/thirdparty.cmake @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + find_program(MAKE_EXE NAMES gmake nmake make) if(${CMAKE_VERSION} VERSION_GREATER "3.23") @@ -12,6 +16,7 @@ endif() # Depends on: nothing # Dependecy of: rocksdb +# License: dual MIT and GPLv2 # We build this manually because alpine doesn't have liburing-static ExternalProject_Add(make_uring DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} @@ -40,6 +45,7 @@ set_target_properties(uring PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/lib/libu # Depends on: none # Dependency of: rocksdb +# License: BSD ExternalProject_Add(make_lz4 DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} URL https://github.com/lz4/lz4/archive/refs/tags/v1.9.4.tar.gz @@ -66,6 +72,7 @@ set_target_properties(lz4 PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/lib/liblz4 # Depends on: none # Dependency of: rocksdb +# License: dual BSD and GPLv2 ExternalProject_Add(make_zstd DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} URL https://github.com/facebook/zstd/archive/refs/tags/v1.5.2.tar.gz @@ -91,6 +98,7 @@ set_target_properties(zstd PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/lib/libzs # Depends on: lz4, zstd # Dependency of: eggs +# License: dual Apache 2.0 and GPLv2 if(${CMAKE_BUILD_TYPE} STREQUAL "valgrind") set(ROCKS_DB_MARCH "-march=haswell") # Valgind can't support current -march=native instructions endif() @@ -133,6 +141,7 @@ set_target_properties(rocksdb PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/lib/li # Depends on: none # Dependency of: eggs +# License: BSD ExternalProject_Add(make_xxhash DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} URL https://github.com/Cyan4973/xxHash/archive/refs/tags/v0.8.1.tar.gz @@ -156,6 +165,7 @@ ExternalProject_Get_property(make_xxhash INSTALL_DIR) include_directories(SYSTEM ${INSTALL_DIR}/include) set_target_properties(xxhash PROPERTIES IMPORTED_LOCATION ${INSTALL_DIR}/lib/libxxhash.a) +# License: BSD ExternalProject_Add(make_jemalloc DOWNLOAD_DIR ${CMAKE_CURRENT_BINARY_DIR} URL https://github.com/jemalloc/jemalloc/releases/download/5.3.0/jemalloc-5.3.0.tar.bz2 diff --git a/cpp/ubsan-ignorelist b/cpp/ubsan-ignorelist index ae5fa039..56c03231 100644 --- a/cpp/ubsan-ignorelist +++ b/cpp/ubsan-ignorelist @@ -1,5 +1,9 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + [integer] # , ticket also # contains some typically funny ranting. src:.*bits/basic_string.h$ -src:.*bits/basic_string.tcc$ \ No newline at end of file +src:.*bits/basic_string.tcc$ diff --git a/cpp/valgrind-suppressions b/cpp/valgrind-suppressions index d5857c79..2ff37bc9 100644 --- a/cpp/valgrind-suppressions +++ b/cpp/valgrind-suppressions @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + # I haven't investigated this -- some uninitialized memory when # invoking libunwind for the first time. { diff --git a/docs/alerts.md b/docs/alerts.md index a095b4ff..69918706 100644 --- a/docs/alerts.md +++ b/docs/alerts.md @@ -1,3 +1,9 @@ + + # Common TernFS alerts and what to do with them * **`ternregistry`** `some decommissioned block services have to be replaced:`. This non-clearable alert is warning you that some drive which has been marked as DECOMMISSIONED has not been replaced. It's not urgent and therefore it's usually silenced, but it does require action eventually. diff --git a/docs/disk-failure.md b/docs/disk-failure.md index ebe34d7c..80a9dae4 100644 --- a/docs/disk-failure.md +++ b/docs/disk-failure.md @@ -1,3 +1,9 @@ + + # Disk Failures ## How TernFS stores files diff --git a/docs/gc.md b/docs/gc.md index d2718c9c..20aeefaa 100644 --- a/docs/gc.md +++ b/docs/gc.md @@ -1,3 +1,9 @@ + + # Garbage Collection ## Snapshots diff --git a/docs/kmod-file-tracking.md b/docs/kmod-file-tracking.md index 8f43e594..9de9c98c 100644 --- a/docs/kmod-file-tracking.md +++ b/docs/kmod-file-tracking.md @@ -1,3 +1,9 @@ + + TernFS files are immutable: they are created once and never modified. This presents a challenge when writing a kernel module for it, since the VFS API very much assumes that files can be modified. So our high level strategy is: allow users to open a file for writing, and keep that file transient (i.e. not visible in the directory tree) until we declare it "done", and do not allow modifications after that. diff --git a/docs/parity.md b/docs/parity.md index b9808144..ad122816 100644 --- a/docs/parity.md +++ b/docs/parity.md @@ -1,3 +1,9 @@ + + TernFS supports erasure coding in any configuration, as long as the parity and data blocks are between 1 and 16 and 0 and 16, respectively. When working with spinning disks we want to not have seek time to dominate the time spent by the block services. diff --git a/go/.gitignore b/go/.gitignore index 2816e375..699e45ab 100644 --- a/go/.gitignore +++ b/go/.gitignore @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + integrationtest/integrationtest ternweb/ternweb ternfuse/ternfuse diff --git a/go/badblocks/badblocks.go b/go/badblocks/badblocks.go index ee1d1327..7c760cfe 100644 --- a/go/badblocks/badblocks.go +++ b/go/badblocks/badblocks.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/bincodegen/FetchedFullSpan.hpp.license b/go/bincodegen/FetchedFullSpan.hpp.license new file mode 100644 index 00000000..250dc46e --- /dev/null +++ b/go/bincodegen/FetchedFullSpan.hpp.license @@ -0,0 +1,3 @@ +Copyright 2025 XTX Markets Technologies Limited + +SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception diff --git a/go/bincodegen/FetchedSpan.hpp.license b/go/bincodegen/FetchedSpan.hpp.license new file mode 100644 index 00000000..250dc46e --- /dev/null +++ b/go/bincodegen/FetchedSpan.hpp.license @@ -0,0 +1,3 @@ +Copyright 2025 XTX Markets Technologies Limited + +SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception diff --git a/go/bincodegen/bincodegen.go b/go/bincodegen/bincodegen.go index f1479e5d..4ed2af80 100644 --- a/go/bincodegen/bincodegen.go +++ b/go/bincodegen/bincodegen.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package main import ( @@ -702,10 +706,22 @@ func generateKmod(errors []string, shardReqResps []reqRespType, cdcReqResps []re hOut := new(bytes.Buffer) cOut := new(bytes.Buffer) + fmt.Fprintln(hOut, "// Copyright 2025 XTX Markets Technologies Limited") + fmt.Fprintln(hOut, "//") + fmt.Fprintln(hOut, "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception") + fmt.Fprintln(hOut) fmt.Fprintln(hOut, "// Automatically generated with go run bincodegen.") fmt.Fprintln(hOut, "// Run `go generate ./...` from the go/ directory to regenerate it.") fmt.Fprintln(hOut) + fmt.Fprintln(cOut, "// Copyright 2025 XTX Markets Technologies Limited") + fmt.Fprintln(cOut, "//") + fmt.Fprintln(cOut, "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception") + fmt.Fprintln(cOut) + fmt.Fprintln(cOut, "// Automatically generated with go run bincodegen.") + fmt.Fprintln(cOut, "// Run `go generate ./...` from the go/ directory to regenerate it.") + fmt.Fprintln(cOut) + for i, err := range errors { fmt.Fprintf(hOut, "#define TERNFS_ERR_%s %d\n", err, ternErrorCodeOffset+i) } @@ -1327,6 +1343,10 @@ func generateCpp(errors []string, shardReqResps []reqRespType, cdcReqResps []req hppOut := new(bytes.Buffer) cppOut := new(bytes.Buffer) + fmt.Fprintln(hppOut, "// Copyright 2025 XTX Markets Technologies Limited") + fmt.Fprintln(hppOut, "//") + fmt.Fprintln(hppOut, "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception") + fmt.Fprintln(hppOut) fmt.Fprintln(hppOut, "// Automatically generated with go run bincodegen.") fmt.Fprintln(hppOut, "// Run `go generate ./...` from the go/ directory to regenerate it.") fmt.Fprintln(hppOut, "#pragma once") @@ -1336,6 +1356,10 @@ func generateCpp(errors []string, shardReqResps []reqRespType, cdcReqResps []req fmt.Fprintln(hppOut, "#include \"Time.hpp\"") fmt.Fprintln(hppOut) + fmt.Fprintln(cppOut, "// Copyright 2025 XTX Markets Technologies Limited") + fmt.Fprintln(cppOut, "//") + fmt.Fprintln(cppOut, "// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception") + fmt.Fprintln(cppOut) fmt.Fprintln(cppOut, "// Automatically generated with go run bincodegen.") fmt.Fprintln(cppOut, "// Run `go generate ./...` from the go/ directory to regenerate it.") fmt.Fprintln(cppOut, "#include \"MsgsGen.hpp\"") diff --git a/go/bincodegen/msgs_bincode.go.header b/go/bincodegen/msgs_bincode.go.header index 531562f6..4b3a81fe 100644 --- a/go/bincodegen/msgs_bincode.go.header +++ b/go/bincodegen/msgs_bincode.go.header @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Automatically generated with go run bincodegen. // Run `go generate ./...` from the go/ directory to regenerate it. package msgs diff --git a/go/build.py b/go/build.py index 0316b586..500235f1 100755 --- a/go/build.py +++ b/go/build.py @@ -1,4 +1,9 @@ #!/usr/bin/env python3 + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + import sys import os from pathlib import Path diff --git a/go/cleanup/collectdirectories.go b/go/cleanup/collectdirectories.go index 9a299899..cb160ed9 100644 --- a/go/cleanup/collectdirectories.go +++ b/go/cleanup/collectdirectories.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package cleanup import ( diff --git a/go/cleanup/defrag.go b/go/cleanup/defrag.go index 26aa6243..bddd8e76 100644 --- a/go/cleanup/defrag.go +++ b/go/cleanup/defrag.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + // Goes through all the _current_ files, and checks that the span block allocation // is coherent with the span policy. Very similar to migration, hence it shares // some datatypes. diff --git a/go/cleanup/destructfiles.go b/go/cleanup/destructfiles.go index 998e1f47..2110c929 100644 --- a/go/cleanup/destructfiles.go +++ b/go/cleanup/destructfiles.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package cleanup import ( diff --git a/go/cleanup/migrate.go b/go/cleanup/migrate.go index e7ccccbc..575e7b53 100644 --- a/go/cleanup/migrate.go +++ b/go/cleanup/migrate.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + // TODO right now we only use one scratch file for everything, which is obviously not // great -- in general this below is more a proof of concept than anything, to test // the right shard code paths. diff --git a/go/cleanup/policy.go b/go/cleanup/policy.go index d0fe074d..ea164357 100644 --- a/go/cleanup/policy.go +++ b/go/cleanup/policy.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package cleanup import ( diff --git a/go/cleanup/policy_test.go b/go/cleanup/policy_test.go index 6b173c0b..06aff357 100644 --- a/go/cleanup/policy_test.go +++ b/go/cleanup/policy_test.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package cleanup import ( diff --git a/go/cleanup/scratch/scratch.go b/go/cleanup/scratch/scratch.go index af2fd557..f281630d 100644 --- a/go/cleanup/scratch/scratch.go +++ b/go/cleanup/scratch/scratch.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package scratch import ( diff --git a/go/cleanup/scrub.go b/go/cleanup/scrub.go index b62d5ad4..d937abb4 100644 --- a/go/cleanup/scrub.go +++ b/go/cleanup/scrub.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package cleanup import ( diff --git a/go/cleanup/zeroblockservicefiles.go b/go/cleanup/zeroblockservicefiles.go index 04bb1de0..fc1a9e41 100644 --- a/go/cleanup/zeroblockservicefiles.go +++ b/go/cleanup/zeroblockservicefiles.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package cleanup import ( diff --git a/go/client/blocksconn_test.go b/go/client/blocksconn_test.go index e4488791..8a44c92e 100644 --- a/go/client/blocksconn_test.go +++ b/go/client/blocksconn_test.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client /* diff --git a/go/client/blocksreq.go b/go/client/blocksreq.go index 987ca8f3..b4abbef6 100644 --- a/go/client/blocksreq.go +++ b/go/client/blocksreq.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/cdcreq.go b/go/client/cdcreq.go index 4ff7462c..a2aabb95 100644 --- a/go/client/cdcreq.go +++ b/go/client/cdcreq.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/client.go b/go/client/client.go index 376f02e6..281d3fd9 100644 --- a/go/client/client.go +++ b/go/client/client.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // The client package provides a interface to the ternfs cluster that should be // sufficient for most user level operations (modifying metadata, reading and // writing blocks, etc). diff --git a/go/client/dirinfocache.go b/go/client/dirinfocache.go index 8ce3e147..0f93bd36 100644 --- a/go/client/dirinfocache.go +++ b/go/client/dirinfocache.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/dirinfocache_test.go b/go/client/dirinfocache_test.go index cfa2a8b1..b486a547 100644 --- a/go/client/dirinfocache_test.go +++ b/go/client/dirinfocache_test.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/metadatareq.go b/go/client/metadatareq.go index cc1e8e45..20b2f16a 100644 --- a/go/client/metadatareq.go +++ b/go/client/metadatareq.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/parwalk.go b/go/client/parwalk.go index 37f7f454..54853cd8 100644 --- a/go/client/parwalk.go +++ b/go/client/parwalk.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // When you want to traverse the filesystem, but you also want the // filepath. We have some workers per shard, to try to parallelize // the work nicely. However there is a work-stealing of sorts otherwise diff --git a/go/client/registryreq.go b/go/client/registryreq.go index 6c0ba32f..773002f0 100644 --- a/go/client/registryreq.go +++ b/go/client/registryreq.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/shardreq.go b/go/client/shardreq.go index 1e658094..3a76d43f 100644 --- a/go/client/shardreq.go +++ b/go/client/shardreq.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/span.go b/go/client/span.go index fac312c1..ef5264c9 100644 --- a/go/client/span.go +++ b/go/client/span.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/client/waitregistry.go b/go/client/waitregistry.go index 03b31897..07716ac9 100644 --- a/go/client/waitregistry.go +++ b/go/client/waitregistry.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package client import ( diff --git a/go/core/assert/assert.go b/go/core/assert/assert.go index 192a395d..e415c740 100644 --- a/go/core/assert/assert.go +++ b/go/core/assert/assert.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package assert import ( diff --git a/go/core/bincode/bincode.go b/go/core/bincode/bincode.go index 019fb523..42b9be9a 100644 --- a/go/core/bincode/bincode.go +++ b/go/core/bincode/bincode.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package bincode import ( diff --git a/go/core/bufpool/bufpool.go b/go/core/bufpool/bufpool.go index 4539d6a4..7906e3ca 100644 --- a/go/core/bufpool/bufpool.go +++ b/go/core/bufpool/bufpool.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package bufpool import ( diff --git a/go/core/cbcmac/cbcmac.go b/go/core/cbcmac/cbcmac.go index 90b9eca4..3d27c222 100644 --- a/go/core/cbcmac/cbcmac.go +++ b/go/core/cbcmac/cbcmac.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package cbcmac import ( diff --git a/go/core/cbcmac/cbcmac_test.go b/go/core/cbcmac/cbcmac_test.go index ab991953..a038506c 100644 --- a/go/core/cbcmac/cbcmac_test.go +++ b/go/core/cbcmac/cbcmac_test.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package cbcmac import ( diff --git a/go/core/certificate/blockscert.go b/go/core/certificate/blockscert.go index 82cac9d5..161a1561 100644 --- a/go/core/certificate/blockscert.go +++ b/go/core/certificate/blockscert.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package certificate import ( diff --git a/go/core/crc32c/crc32c.go b/go/core/crc32c/crc32c.go index efe0ce45..d62a810b 100644 --- a/go/core/crc32c/crc32c.go +++ b/go/core/crc32c/crc32c.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package crc32c // #cgo LDFLAGS: -L${SRCDIR}/../../../cpp/build/alpine/crc32c -lcrc32c diff --git a/go/core/crc32c/crc32c_test.go b/go/core/crc32c/crc32c_test.go index b3b4b722..3f13a86b 100644 --- a/go/core/crc32c/crc32c_test.go +++ b/go/core/crc32c/crc32c_test.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package crc32c import ( diff --git a/go/core/flags/ipv4addr.go b/go/core/flags/ipv4addr.go index c559320f..3c7d8f10 100644 --- a/go/core/flags/ipv4addr.go +++ b/go/core/flags/ipv4addr.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package flags import ( diff --git a/go/core/flags/stringsflag.go b/go/core/flags/stringsflag.go index 70f116de..42278093 100644 --- a/go/core/flags/stringsflag.go +++ b/go/core/flags/stringsflag.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package flags import "fmt" diff --git a/go/core/log/hardwareevent.go b/go/core/log/hardwareevent.go index 2cdedce5..7395c21e 100644 --- a/go/core/log/hardwareevent.go +++ b/go/core/log/hardwareevent.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package log import ( diff --git a/go/core/log/log.go b/go/core/log/log.go index c09b4e1e..a2f28856 100644 --- a/go/core/log/log.go +++ b/go/core/log/log.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package log import ( diff --git a/go/core/log/metrics.go b/go/core/log/metrics.go index 6861eac9..bc714289 100644 --- a/go/core/log/metrics.go +++ b/go/core/log/metrics.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // See // for docs. package log diff --git a/go/core/log/xmon.go b/go/core/log/xmon.go index 700ae431..5c3b91ef 100644 --- a/go/core/log/xmon.go +++ b/go/core/log/xmon.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package log import ( diff --git a/go/core/managedprocess/managedprocess.go b/go/core/managedprocess/managedprocess.go index 116e3724..b988e3bc 100644 --- a/go/core/managedprocess/managedprocess.go +++ b/go/core/managedprocess/managedprocess.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Useful when we have an application which spawns some process and wants to tear down all // of them when it goes down, and also wants to go down itself if any of the processes // terminates. diff --git a/go/core/managedroutine/managedroutine.go b/go/core/managedroutine/managedroutine.go index bd994551..2126e30d 100644 --- a/go/core/managedroutine/managedroutine.go +++ b/go/core/managedroutine/managedroutine.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package managedroutine import ( diff --git a/go/core/parity/parity.go b/go/core/parity/parity.go index c42b3a06..8d64e5bb 100644 --- a/go/core/parity/parity.go +++ b/go/core/parity/parity.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package parity import ( diff --git a/go/core/recover/recover.go b/go/core/recover/recover.go index 4212c619..3cc6fe26 100644 --- a/go/core/recover/recover.go +++ b/go/core/recover/recover.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package recover import ( diff --git a/go/core/rs/rs.go b/go/core/rs/rs.go index fdf8971f..af26a099 100644 --- a/go/core/rs/rs.go +++ b/go/core/rs/rs.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package rs import ( diff --git a/go/core/rs/rs_test.go b/go/core/rs/rs_test.go index af9a3dde..006d632c 100644 --- a/go/core/rs/rs_test.go +++ b/go/core/rs/rs_test.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package rs import ( diff --git a/go/core/timing/histogram.go b/go/core/timing/histogram.go index 4b690921..5762196f 100644 --- a/go/core/timing/histogram.go +++ b/go/core/timing/histogram.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package timing import ( diff --git a/go/core/timing/ratelimit.go b/go/core/timing/ratelimit.go index 3fcd7ad9..cc620eb5 100644 --- a/go/core/timing/ratelimit.go +++ b/go/core/timing/ratelimit.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package timing import ( diff --git a/go/core/timing/timeouts.go b/go/core/timing/timeouts.go index f1676d09..ba4363b0 100644 --- a/go/core/timing/timeouts.go +++ b/go/core/timing/timeouts.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package timing import ( diff --git a/go/core/timing/timings.go b/go/core/timing/timings.go index c5ffe866..8dfeed61 100644 --- a/go/core/timing/timings.go +++ b/go/core/timing/timings.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package timing import ( diff --git a/go/core/timing/timings_test.go b/go/core/timing/timings_test.go index 69941d03..9c9aaa21 100644 --- a/go/core/timing/timings_test.go +++ b/go/core/timing/timings_test.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package timing import ( diff --git a/go/core/wyhash/wyhash.go b/go/core/wyhash/wyhash.go index cf2ebd2d..26dc7d03 100644 --- a/go/core/wyhash/wyhash.go +++ b/go/core/wyhash/wyhash.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // See wyhash.h, this used to be using FFI, but I had not // realized that bits.Mul64 existed, and also that FFI is // pretty slow in Go. diff --git a/go/crc32csum/crc32csum.go b/go/crc32csum/crc32csum.go index 386c1136..c80a727a 100644 --- a/go/crc32csum/crc32csum.go +++ b/go/crc32csum/crc32csum.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package main import ( diff --git a/go/msgs/msgs.go b/go/msgs/msgs.go index 9929fa36..40933d0b 100644 --- a/go/msgs/msgs.go +++ b/go/msgs/msgs.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // See bincodegen.go for more comments on how we split op these operations package msgs diff --git a/go/msgs/msgs_bincode.go b/go/msgs/msgs_bincode.go index 5183bd3e..1ed06224 100644 --- a/go/msgs/msgs_bincode.go +++ b/go/msgs/msgs_bincode.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Automatically generated with go run bincodegen. // Run `go generate ./...` from the go/ directory to regenerate it. package msgs diff --git a/go/msgs/public/public.go b/go/msgs/public/public.go index d7f7235e..ced5da0f 100644 --- a/go/msgs/public/public.go +++ b/go/msgs/public/public.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + package public import "fmt" diff --git a/go/s3/s3.go b/go/s3/s3.go index 676b1417..cea48a6e 100644 --- a/go/s3/s3.go +++ b/go/s3/s3.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package s3 import ( diff --git a/go/ternblocks/ternblocks.go b/go/ternblocks/ternblocks.go index ca7d8cff..47330ab8 100644 --- a/go/ternblocks/ternblocks.go +++ b/go/ternblocks/ternblocks.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terncli/filesamples/filesamples.go b/go/terncli/filesamples/filesamples.go index 3a8accf3..5532a833 100644 --- a/go/terncli/filesamples/filesamples.go +++ b/go/terncli/filesamples/filesamples.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package filesamples import ( diff --git a/go/terncli/kernelmetrics.go b/go/terncli/kernelmetrics.go index 9831a67c..aeb2ec19 100644 --- a/go/terncli/kernelmetrics.go +++ b/go/terncli/kernelmetrics.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terncli/terncli.go b/go/terncli/terncli.go index 707a4656..277aea65 100644 --- a/go/terncli/terncli.go +++ b/go/terncli/terncli.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/ternfuse/ternfuse.go b/go/ternfuse/ternfuse.go index 319d481a..e18a3060 100644 --- a/go/ternfuse/ternfuse.go +++ b/go/ternfuse/ternfuse.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terngc/terngc.go b/go/terngc/terngc.go index 835706f8..021e14a8 100644 --- a/go/terngc/terngc.go +++ b/go/terngc/terngc.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/ternregistryproxy/ternregistryproxy.go b/go/ternregistryproxy/ternregistryproxy.go index 6ec1643e..fe9c2b9d 100644 --- a/go/ternregistryproxy/ternregistryproxy.go +++ b/go/ternregistryproxy/ternregistryproxy.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/ternrun/ternrun.go b/go/ternrun/ternrun.go index 6dec096e..9c9c2e19 100644 --- a/go/ternrun/ternrun.go +++ b/go/ternrun/ternrun.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + // Utility to quickly bring up a full ternfs, including all its components, // while hopefully not leaking processes left and right when this process dies. package main diff --git a/go/terns3/terns3.go b/go/terns3/terns3.go index ffc318ed..52b56d49 100644 --- a/go/terns3/terns3.go +++ b/go/terns3/terns3.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/cleanup.go b/go/terntests/cleanup.go index a61a5c14..b4bfd9f1 100644 --- a/go/terntests/cleanup.go +++ b/go/terntests/cleanup.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/dirseek.go b/go/terntests/dirseek.go index 920882b7..b4a6afe6 100644 --- a/go/terntests/dirseek.go +++ b/go/terntests/dirseek.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/filehistory.go b/go/terntests/filehistory.go index 940c2e40..21da7308 100644 --- a/go/terntests/filehistory.go +++ b/go/terntests/filehistory.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + // A simple tests creating files looking at the history package main diff --git a/go/terntests/fstest.go b/go/terntests/fstest.go index c4994245..2cff965f 100644 --- a/go/terntests/fstest.go +++ b/go/terntests/fstest.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + // Very simple test creating some directory tree and reading it back package main diff --git a/go/terntests/largefile.go b/go/terntests/largefile.go index c9941534..e530e7cb 100644 --- a/go/terntests/largefile.go +++ b/go/terntests/largefile.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/paralleldirs.go b/go/terntests/paralleldirs.go index a37971eb..b39c9a42 100644 --- a/go/terntests/paralleldirs.go +++ b/go/terntests/paralleldirs.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/preaddir.go b/go/terntests/preaddir.go index 63cd098b..3123ae52 100644 --- a/go/terntests/preaddir.go +++ b/go/terntests/preaddir.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/req.go b/go/terntests/req.go index 4a50f603..c5fcfcb0 100644 --- a/go/terntests/req.go +++ b/go/terntests/req.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/rsynctest.go b/go/terntests/rsynctest.go index 12181582..33f83ee1 100644 --- a/go/terntests/rsynctest.go +++ b/go/terntests/rsynctest.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/terntests/terntests.go b/go/terntests/terntests.go index 5ab87c66..6f56fde4 100644 --- a/go/terntests/terntests.go +++ b/go/terntests/terntests.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( diff --git a/go/ternweb/base.html b/go/ternweb/base.html index 87fa617e..502fde0d 100644 --- a/go/ternweb/base.html +++ b/go/ternweb/base.html @@ -1,3 +1,9 @@ + + diff --git a/go/ternweb/bootstrap.5.0.2.min.css b/go/ternweb/bootstrap.5.0.2.min.css index edfbbb03..a21b0c9f 100644 --- a/go/ternweb/bootstrap.5.0.2.min.css +++ b/go/ternweb/bootstrap.5.0.2.min.css @@ -2,6 +2,6 @@ * Bootstrap v5.0.2 (https://getbootstrap.com/) * Copyright 2011-2021 The Bootstrap Authors * Copyright 2011-2021 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * SPDX-License-Identifier: MIT */:root{--bs-blue:#0d6efd;--bs-indigo:#6610f2;--bs-purple:#6f42c1;--bs-pink:#d63384;--bs-red:#dc3545;--bs-orange:#fd7e14;--bs-yellow:#ffc107;--bs-green:#198754;--bs-teal:#20c997;--bs-cyan:#0dcaf0;--bs-white:#fff;--bs-gray:#6c757d;--bs-gray-dark:#343a40;--bs-primary:#0d6efd;--bs-secondary:#6c757d;--bs-success:#198754;--bs-info:#0dcaf0;--bs-warning:#ffc107;--bs-danger:#dc3545;--bs-light:#f8f9fa;--bs-dark:#212529;--bs-font-sans-serif:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--bs-font-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--bs-gradient:linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0))}*,::after,::before{box-sizing:border-box}@media (prefers-reduced-motion:no-preference){:root{scroll-behavior:smooth}}body{margin:0;font-family:var(--bs-font-sans-serif);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}hr{margin:1rem 0;color:inherit;background-color:currentColor;border:0;opacity:.25}hr:not([size]){height:1px}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:calc(1.375rem + 1.5vw)}@media (min-width:1200px){.h1,h1{font-size:2.5rem}}.h2,h2{font-size:calc(1.325rem + .9vw)}@media (min-width:1200px){.h2,h2{font-size:2rem}}.h3,h3{font-size:calc(1.3rem + .6vw)}@media (min-width:1200px){.h3,h3{font-size:1.75rem}}.h4,h4{font-size:calc(1.275rem + .3vw)}@media (min-width:1200px){.h4,h4{font-size:1.5rem}}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}p{margin-top:0;margin-bottom:1rem}abbr[data-bs-original-title],abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}ol,ul{padding-left:2rem}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}.small,small{font-size:.875em}.mark,mark{padding:.2em;background-color:#fcf8e3}sub,sup{position:relative;font-size:.75em;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#0d6efd;text-decoration:underline}a:hover{color:#0a58ca}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:var(--bs-font-monospace);font-size:1em;direction:ltr;unicode-bidi:bidi-override}pre{display:block;margin-top:0;margin-bottom:1rem;overflow:auto;font-size:.875em}pre code{font-size:inherit;color:inherit;word-break:normal}code{font-size:.875em;color:#d63384;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:.875em;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:1em;font-weight:700}figure{margin:0 0 1rem}img,svg{vertical-align:middle}table{caption-side:bottom;border-collapse:collapse}caption{padding-top:.5rem;padding-bottom:.5rem;color:#6c757d;text-align:left}th{text-align:inherit;text-align:-webkit-match-parent}tbody,td,tfoot,th,thead,tr{border-color:inherit;border-style:solid;border-width:0}label{display:inline-block}button{border-radius:0}button:focus:not(:focus-visible){outline:0}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}select:disabled{opacity:1}[list]::-webkit-calendar-picker-indicator{display:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}::-moz-focus-inner{padding:0;border-style:none}textarea{resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{float:left;width:100%;padding:0;margin-bottom:.5rem;font-size:calc(1.275rem + .3vw);line-height:inherit}@media (min-width:1200px){legend{font-size:1.5rem}}legend+*{clear:left}::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-fields-wrapper,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-text,::-webkit-datetime-edit-year-field{padding:0}::-webkit-inner-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:textfield}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-color-swatch-wrapper{padding:0}::file-selector-button{font:inherit}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}iframe{border:0}summary{display:list-item;cursor:pointer}progress{vertical-align:baseline}[hidden]{display:none!important}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:calc(1.625rem + 4.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-1{font-size:5rem}}.display-2{font-size:calc(1.575rem + 3.9vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-2{font-size:4.5rem}}.display-3{font-size:calc(1.525rem + 3.3vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-3{font-size:4rem}}.display-4{font-size:calc(1.475rem + 2.7vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-4{font-size:3.5rem}}.display-5{font-size:calc(1.425rem + 2.1vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-5{font-size:3rem}}.display-6{font-size:calc(1.375rem + 1.5vw);font-weight:300;line-height:1.2}@media (min-width:1200px){.display-6{font-size:2.5rem}}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:.875em;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote>:last-child{margin-bottom:0}.blockquote-footer{margin-top:-1rem;margin-bottom:1rem;font-size:.875em;color:#6c757d}.blockquote-footer::before{content:"— "}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:.875em;color:#6c757d}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{width:100%;padding-right:var(--bs-gutter-x,.75rem);padding-left:var(--bs-gutter-x,.75rem);margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}@media (min-width:1400px){.container,.container-lg,.container-md,.container-sm,.container-xl,.container-xxl{max-width:1320px}}.row{--bs-gutter-x:1.5rem;--bs-gutter-y:0;display:flex;flex-wrap:wrap;margin-top:calc(var(--bs-gutter-y) * -1);margin-right:calc(var(--bs-gutter-x) * -.5);margin-left:calc(var(--bs-gutter-x) * -.5)}.row>*{flex-shrink:0;width:100%;max-width:100%;padding-right:calc(var(--bs-gutter-x) * .5);padding-left:calc(var(--bs-gutter-x) * .5);margin-top:var(--bs-gutter-y)}.col{flex:1 0 0%}.row-cols-auto>*{flex:0 0 auto;width:auto}.row-cols-1>*{flex:0 0 auto;width:100%}.row-cols-2>*{flex:0 0 auto;width:50%}.row-cols-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-4>*{flex:0 0 auto;width:25%}.row-cols-5>*{flex:0 0 auto;width:20%}.row-cols-6>*{flex:0 0 auto;width:16.6666666667%}@media (min-width:576px){.col-sm{flex:1 0 0%}.row-cols-sm-auto>*{flex:0 0 auto;width:auto}.row-cols-sm-1>*{flex:0 0 auto;width:100%}.row-cols-sm-2>*{flex:0 0 auto;width:50%}.row-cols-sm-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 auto;width:25%}.row-cols-sm-5>*{flex:0 0 auto;width:20%}.row-cols-sm-6>*{flex:0 0 auto;width:16.6666666667%}}@media (min-width:768px){.col-md{flex:1 0 0%}.row-cols-md-auto>*{flex:0 0 auto;width:auto}.row-cols-md-1>*{flex:0 0 auto;width:100%}.row-cols-md-2>*{flex:0 0 auto;width:50%}.row-cols-md-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-md-4>*{flex:0 0 auto;width:25%}.row-cols-md-5>*{flex:0 0 auto;width:20%}.row-cols-md-6>*{flex:0 0 auto;width:16.6666666667%}}@media (min-width:992px){.col-lg{flex:1 0 0%}.row-cols-lg-auto>*{flex:0 0 auto;width:auto}.row-cols-lg-1>*{flex:0 0 auto;width:100%}.row-cols-lg-2>*{flex:0 0 auto;width:50%}.row-cols-lg-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 auto;width:25%}.row-cols-lg-5>*{flex:0 0 auto;width:20%}.row-cols-lg-6>*{flex:0 0 auto;width:16.6666666667%}}@media (min-width:1200px){.col-xl{flex:1 0 0%}.row-cols-xl-auto>*{flex:0 0 auto;width:auto}.row-cols-xl-1>*{flex:0 0 auto;width:100%}.row-cols-xl-2>*{flex:0 0 auto;width:50%}.row-cols-xl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 auto;width:25%}.row-cols-xl-5>*{flex:0 0 auto;width:20%}.row-cols-xl-6>*{flex:0 0 auto;width:16.6666666667%}}@media (min-width:1400px){.col-xxl{flex:1 0 0%}.row-cols-xxl-auto>*{flex:0 0 auto;width:auto}.row-cols-xxl-1>*{flex:0 0 auto;width:100%}.row-cols-xxl-2>*{flex:0 0 auto;width:50%}.row-cols-xxl-3>*{flex:0 0 auto;width:33.3333333333%}.row-cols-xxl-4>*{flex:0 0 auto;width:25%}.row-cols-xxl-5>*{flex:0 0 auto;width:20%}.row-cols-xxl-6>*{flex:0 0 auto;width:16.6666666667%}}.col-auto{flex:0 0 auto;width:auto}.col-1{flex:0 0 auto;width:8.33333333%}.col-2{flex:0 0 auto;width:16.66666667%}.col-3{flex:0 0 auto;width:25%}.col-4{flex:0 0 auto;width:33.33333333%}.col-5{flex:0 0 auto;width:41.66666667%}.col-6{flex:0 0 auto;width:50%}.col-7{flex:0 0 auto;width:58.33333333%}.col-8{flex:0 0 auto;width:66.66666667%}.col-9{flex:0 0 auto;width:75%}.col-10{flex:0 0 auto;width:83.33333333%}.col-11{flex:0 0 auto;width:91.66666667%}.col-12{flex:0 0 auto;width:100%}.offset-1{margin-left:8.33333333%}.offset-2{margin-left:16.66666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333%}.offset-5{margin-left:41.66666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.33333333%}.offset-8{margin-left:66.66666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333%}.offset-11{margin-left:91.66666667%}.g-0,.gx-0{--bs-gutter-x:0}.g-0,.gy-0{--bs-gutter-y:0}.g-1,.gx-1{--bs-gutter-x:0.25rem}.g-1,.gy-1{--bs-gutter-y:0.25rem}.g-2,.gx-2{--bs-gutter-x:0.5rem}.g-2,.gy-2{--bs-gutter-y:0.5rem}.g-3,.gx-3{--bs-gutter-x:1rem}.g-3,.gy-3{--bs-gutter-y:1rem}.g-4,.gx-4{--bs-gutter-x:1.5rem}.g-4,.gy-4{--bs-gutter-y:1.5rem}.g-5,.gx-5{--bs-gutter-x:3rem}.g-5,.gy-5{--bs-gutter-y:3rem}@media (min-width:576px){.col-sm-auto{flex:0 0 auto;width:auto}.col-sm-1{flex:0 0 auto;width:8.33333333%}.col-sm-2{flex:0 0 auto;width:16.66666667%}.col-sm-3{flex:0 0 auto;width:25%}.col-sm-4{flex:0 0 auto;width:33.33333333%}.col-sm-5{flex:0 0 auto;width:41.66666667%}.col-sm-6{flex:0 0 auto;width:50%}.col-sm-7{flex:0 0 auto;width:58.33333333%}.col-sm-8{flex:0 0 auto;width:66.66666667%}.col-sm-9{flex:0 0 auto;width:75%}.col-sm-10{flex:0 0 auto;width:83.33333333%}.col-sm-11{flex:0 0 auto;width:91.66666667%}.col-sm-12{flex:0 0 auto;width:100%}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.33333333%}.offset-sm-2{margin-left:16.66666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.33333333%}.offset-sm-5{margin-left:41.66666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.33333333%}.offset-sm-8{margin-left:66.66666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.33333333%}.offset-sm-11{margin-left:91.66666667%}.g-sm-0,.gx-sm-0{--bs-gutter-x:0}.g-sm-0,.gy-sm-0{--bs-gutter-y:0}.g-sm-1,.gx-sm-1{--bs-gutter-x:0.25rem}.g-sm-1,.gy-sm-1{--bs-gutter-y:0.25rem}.g-sm-2,.gx-sm-2{--bs-gutter-x:0.5rem}.g-sm-2,.gy-sm-2{--bs-gutter-y:0.5rem}.g-sm-3,.gx-sm-3{--bs-gutter-x:1rem}.g-sm-3,.gy-sm-3{--bs-gutter-y:1rem}.g-sm-4,.gx-sm-4{--bs-gutter-x:1.5rem}.g-sm-4,.gy-sm-4{--bs-gutter-y:1.5rem}.g-sm-5,.gx-sm-5{--bs-gutter-x:3rem}.g-sm-5,.gy-sm-5{--bs-gutter-y:3rem}}@media (min-width:768px){.col-md-auto{flex:0 0 auto;width:auto}.col-md-1{flex:0 0 auto;width:8.33333333%}.col-md-2{flex:0 0 auto;width:16.66666667%}.col-md-3{flex:0 0 auto;width:25%}.col-md-4{flex:0 0 auto;width:33.33333333%}.col-md-5{flex:0 0 auto;width:41.66666667%}.col-md-6{flex:0 0 auto;width:50%}.col-md-7{flex:0 0 auto;width:58.33333333%}.col-md-8{flex:0 0 auto;width:66.66666667%}.col-md-9{flex:0 0 auto;width:75%}.col-md-10{flex:0 0 auto;width:83.33333333%}.col-md-11{flex:0 0 auto;width:91.66666667%}.col-md-12{flex:0 0 auto;width:100%}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.33333333%}.offset-md-2{margin-left:16.66666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.33333333%}.offset-md-5{margin-left:41.66666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.33333333%}.offset-md-8{margin-left:66.66666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.33333333%}.offset-md-11{margin-left:91.66666667%}.g-md-0,.gx-md-0{--bs-gutter-x:0}.g-md-0,.gy-md-0{--bs-gutter-y:0}.g-md-1,.gx-md-1{--bs-gutter-x:0.25rem}.g-md-1,.gy-md-1{--bs-gutter-y:0.25rem}.g-md-2,.gx-md-2{--bs-gutter-x:0.5rem}.g-md-2,.gy-md-2{--bs-gutter-y:0.5rem}.g-md-3,.gx-md-3{--bs-gutter-x:1rem}.g-md-3,.gy-md-3{--bs-gutter-y:1rem}.g-md-4,.gx-md-4{--bs-gutter-x:1.5rem}.g-md-4,.gy-md-4{--bs-gutter-y:1.5rem}.g-md-5,.gx-md-5{--bs-gutter-x:3rem}.g-md-5,.gy-md-5{--bs-gutter-y:3rem}}@media (min-width:992px){.col-lg-auto{flex:0 0 auto;width:auto}.col-lg-1{flex:0 0 auto;width:8.33333333%}.col-lg-2{flex:0 0 auto;width:16.66666667%}.col-lg-3{flex:0 0 auto;width:25%}.col-lg-4{flex:0 0 auto;width:33.33333333%}.col-lg-5{flex:0 0 auto;width:41.66666667%}.col-lg-6{flex:0 0 auto;width:50%}.col-lg-7{flex:0 0 auto;width:58.33333333%}.col-lg-8{flex:0 0 auto;width:66.66666667%}.col-lg-9{flex:0 0 auto;width:75%}.col-lg-10{flex:0 0 auto;width:83.33333333%}.col-lg-11{flex:0 0 auto;width:91.66666667%}.col-lg-12{flex:0 0 auto;width:100%}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.33333333%}.offset-lg-2{margin-left:16.66666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.33333333%}.offset-lg-5{margin-left:41.66666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.33333333%}.offset-lg-8{margin-left:66.66666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.33333333%}.offset-lg-11{margin-left:91.66666667%}.g-lg-0,.gx-lg-0{--bs-gutter-x:0}.g-lg-0,.gy-lg-0{--bs-gutter-y:0}.g-lg-1,.gx-lg-1{--bs-gutter-x:0.25rem}.g-lg-1,.gy-lg-1{--bs-gutter-y:0.25rem}.g-lg-2,.gx-lg-2{--bs-gutter-x:0.5rem}.g-lg-2,.gy-lg-2{--bs-gutter-y:0.5rem}.g-lg-3,.gx-lg-3{--bs-gutter-x:1rem}.g-lg-3,.gy-lg-3{--bs-gutter-y:1rem}.g-lg-4,.gx-lg-4{--bs-gutter-x:1.5rem}.g-lg-4,.gy-lg-4{--bs-gutter-y:1.5rem}.g-lg-5,.gx-lg-5{--bs-gutter-x:3rem}.g-lg-5,.gy-lg-5{--bs-gutter-y:3rem}}@media (min-width:1200px){.col-xl-auto{flex:0 0 auto;width:auto}.col-xl-1{flex:0 0 auto;width:8.33333333%}.col-xl-2{flex:0 0 auto;width:16.66666667%}.col-xl-3{flex:0 0 auto;width:25%}.col-xl-4{flex:0 0 auto;width:33.33333333%}.col-xl-5{flex:0 0 auto;width:41.66666667%}.col-xl-6{flex:0 0 auto;width:50%}.col-xl-7{flex:0 0 auto;width:58.33333333%}.col-xl-8{flex:0 0 auto;width:66.66666667%}.col-xl-9{flex:0 0 auto;width:75%}.col-xl-10{flex:0 0 auto;width:83.33333333%}.col-xl-11{flex:0 0 auto;width:91.66666667%}.col-xl-12{flex:0 0 auto;width:100%}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.33333333%}.offset-xl-2{margin-left:16.66666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.33333333%}.offset-xl-5{margin-left:41.66666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.33333333%}.offset-xl-8{margin-left:66.66666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.33333333%}.offset-xl-11{margin-left:91.66666667%}.g-xl-0,.gx-xl-0{--bs-gutter-x:0}.g-xl-0,.gy-xl-0{--bs-gutter-y:0}.g-xl-1,.gx-xl-1{--bs-gutter-x:0.25rem}.g-xl-1,.gy-xl-1{--bs-gutter-y:0.25rem}.g-xl-2,.gx-xl-2{--bs-gutter-x:0.5rem}.g-xl-2,.gy-xl-2{--bs-gutter-y:0.5rem}.g-xl-3,.gx-xl-3{--bs-gutter-x:1rem}.g-xl-3,.gy-xl-3{--bs-gutter-y:1rem}.g-xl-4,.gx-xl-4{--bs-gutter-x:1.5rem}.g-xl-4,.gy-xl-4{--bs-gutter-y:1.5rem}.g-xl-5,.gx-xl-5{--bs-gutter-x:3rem}.g-xl-5,.gy-xl-5{--bs-gutter-y:3rem}}@media (min-width:1400px){.col-xxl-auto{flex:0 0 auto;width:auto}.col-xxl-1{flex:0 0 auto;width:8.33333333%}.col-xxl-2{flex:0 0 auto;width:16.66666667%}.col-xxl-3{flex:0 0 auto;width:25%}.col-xxl-4{flex:0 0 auto;width:33.33333333%}.col-xxl-5{flex:0 0 auto;width:41.66666667%}.col-xxl-6{flex:0 0 auto;width:50%}.col-xxl-7{flex:0 0 auto;width:58.33333333%}.col-xxl-8{flex:0 0 auto;width:66.66666667%}.col-xxl-9{flex:0 0 auto;width:75%}.col-xxl-10{flex:0 0 auto;width:83.33333333%}.col-xxl-11{flex:0 0 auto;width:91.66666667%}.col-xxl-12{flex:0 0 auto;width:100%}.offset-xxl-0{margin-left:0}.offset-xxl-1{margin-left:8.33333333%}.offset-xxl-2{margin-left:16.66666667%}.offset-xxl-3{margin-left:25%}.offset-xxl-4{margin-left:33.33333333%}.offset-xxl-5{margin-left:41.66666667%}.offset-xxl-6{margin-left:50%}.offset-xxl-7{margin-left:58.33333333%}.offset-xxl-8{margin-left:66.66666667%}.offset-xxl-9{margin-left:75%}.offset-xxl-10{margin-left:83.33333333%}.offset-xxl-11{margin-left:91.66666667%}.g-xxl-0,.gx-xxl-0{--bs-gutter-x:0}.g-xxl-0,.gy-xxl-0{--bs-gutter-y:0}.g-xxl-1,.gx-xxl-1{--bs-gutter-x:0.25rem}.g-xxl-1,.gy-xxl-1{--bs-gutter-y:0.25rem}.g-xxl-2,.gx-xxl-2{--bs-gutter-x:0.5rem}.g-xxl-2,.gy-xxl-2{--bs-gutter-y:0.5rem}.g-xxl-3,.gx-xxl-3{--bs-gutter-x:1rem}.g-xxl-3,.gy-xxl-3{--bs-gutter-y:1rem}.g-xxl-4,.gx-xxl-4{--bs-gutter-x:1.5rem}.g-xxl-4,.gy-xxl-4{--bs-gutter-y:1.5rem}.g-xxl-5,.gx-xxl-5{--bs-gutter-x:3rem}.g-xxl-5,.gy-xxl-5{--bs-gutter-y:3rem}}.table{--bs-table-bg:transparent;--bs-table-accent-bg:transparent;--bs-table-striped-color:#212529;--bs-table-striped-bg:rgba(0, 0, 0, 0.05);--bs-table-active-color:#212529;--bs-table-active-bg:rgba(0, 0, 0, 0.1);--bs-table-hover-color:#212529;--bs-table-hover-bg:rgba(0, 0, 0, 0.075);width:100%;margin-bottom:1rem;color:#212529;vertical-align:top;border-color:#dee2e6}.table>:not(caption)>*>*{padding:.5rem .5rem;background-color:var(--bs-table-bg);border-bottom-width:1px;box-shadow:inset 0 0 0 9999px var(--bs-table-accent-bg)}.table>tbody{vertical-align:inherit}.table>thead{vertical-align:bottom}.table>:not(:last-child)>:last-child>*{border-bottom-color:currentColor}.caption-top{caption-side:top}.table-sm>:not(caption)>*>*{padding:.25rem .25rem}.table-bordered>:not(caption)>*{border-width:1px 0}.table-bordered>:not(caption)>*>*{border-width:0 1px}.table-borderless>:not(caption)>*>*{border-bottom-width:0}.table-striped>tbody>tr:nth-of-type(odd){--bs-table-accent-bg:var(--bs-table-striped-bg);color:var(--bs-table-striped-color)}.table-active{--bs-table-accent-bg:var(--bs-table-active-bg);color:var(--bs-table-active-color)}.table-hover>tbody>tr:hover{--bs-table-accent-bg:var(--bs-table-hover-bg);color:var(--bs-table-hover-color)}.table-primary{--bs-table-bg:#cfe2ff;--bs-table-striped-bg:#c5d7f2;--bs-table-striped-color:#000;--bs-table-active-bg:#bacbe6;--bs-table-active-color:#000;--bs-table-hover-bg:#bfd1ec;--bs-table-hover-color:#000;color:#000;border-color:#bacbe6}.table-secondary{--bs-table-bg:#e2e3e5;--bs-table-striped-bg:#d7d8da;--bs-table-striped-color:#000;--bs-table-active-bg:#cbccce;--bs-table-active-color:#000;--bs-table-hover-bg:#d1d2d4;--bs-table-hover-color:#000;color:#000;border-color:#cbccce}.table-success{--bs-table-bg:#d1e7dd;--bs-table-striped-bg:#c7dbd2;--bs-table-striped-color:#000;--bs-table-active-bg:#bcd0c7;--bs-table-active-color:#000;--bs-table-hover-bg:#c1d6cc;--bs-table-hover-color:#000;color:#000;border-color:#bcd0c7}.table-info{--bs-table-bg:#cff4fc;--bs-table-striped-bg:#c5e8ef;--bs-table-striped-color:#000;--bs-table-active-bg:#badce3;--bs-table-active-color:#000;--bs-table-hover-bg:#bfe2e9;--bs-table-hover-color:#000;color:#000;border-color:#badce3}.table-warning{--bs-table-bg:#fff3cd;--bs-table-striped-bg:#f2e7c3;--bs-table-striped-color:#000;--bs-table-active-bg:#e6dbb9;--bs-table-active-color:#000;--bs-table-hover-bg:#ece1be;--bs-table-hover-color:#000;color:#000;border-color:#e6dbb9}.table-danger{--bs-table-bg:#f8d7da;--bs-table-striped-bg:#eccccf;--bs-table-striped-color:#000;--bs-table-active-bg:#dfc2c4;--bs-table-active-color:#000;--bs-table-hover-bg:#e5c7ca;--bs-table-hover-color:#000;color:#000;border-color:#dfc2c4}.table-light{--bs-table-bg:#f8f9fa;--bs-table-striped-bg:#ecedee;--bs-table-striped-color:#000;--bs-table-active-bg:#dfe0e1;--bs-table-active-color:#000;--bs-table-hover-bg:#e5e6e7;--bs-table-hover-color:#000;color:#000;border-color:#dfe0e1}.table-dark{--bs-table-bg:#212529;--bs-table-striped-bg:#2c3034;--bs-table-striped-color:#fff;--bs-table-active-bg:#373b3e;--bs-table-active-color:#fff;--bs-table-hover-bg:#323539;--bs-table-hover-color:#fff;color:#fff;border-color:#373b3e}.table-responsive{overflow-x:auto;-webkit-overflow-scrolling:touch}@media (max-width:575.98px){.table-responsive-sm{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:767.98px){.table-responsive-md{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:991.98px){.table-responsive-lg{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1199.98px){.table-responsive-xl{overflow-x:auto;-webkit-overflow-scrolling:touch}}@media (max-width:1399.98px){.table-responsive-xxl{overflow-x:auto;-webkit-overflow-scrolling:touch}}.form-label{margin-bottom:.5rem}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem}.form-text{margin-top:.25rem;font-size:.875em;color:#6c757d}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control[type=file]{overflow:hidden}.form-control[type=file]:not(:disabled):not([readonly]){cursor:pointer}.form-control:focus{color:#212529;background-color:#fff;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-control::-webkit-date-and-time-value{height:1.5em}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}.form-control::file-selector-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::file-selector-button{transition:none}}.form-control:hover:not(:disabled):not([readonly])::file-selector-button{background-color:#dde0e3}.form-control::-webkit-file-upload-button{padding:.375rem .75rem;margin:-.375rem -.75rem;-webkit-margin-end:.75rem;margin-inline-end:.75rem;color:#212529;background-color:#e9ecef;pointer-events:none;border-color:inherit;border-style:solid;border-width:0;border-inline-end-width:1px;border-radius:0;-webkit-transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control::-webkit-file-upload-button{-webkit-transition:none;transition:none}}.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button{background-color:#dde0e3}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{min-height:calc(1.5em + (.5rem + 2px));padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.form-control-sm::file-selector-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-sm::-webkit-file-upload-button{padding:.25rem .5rem;margin:-.25rem -.5rem;-webkit-margin-end:.5rem;margin-inline-end:.5rem}.form-control-lg{min-height:calc(1.5em + (1rem + 2px));padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.form-control-lg::file-selector-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}.form-control-lg::-webkit-file-upload-button{padding:.5rem 1rem;margin:-.5rem -1rem;-webkit-margin-end:1rem;margin-inline-end:1rem}textarea.form-control{min-height:calc(1.5em + (.75rem + 2px))}textarea.form-control-sm{min-height:calc(1.5em + (.5rem + 2px))}textarea.form-control-lg{min-height:calc(1.5em + (1rem + 2px))}.form-control-color{max-width:3rem;height:auto;padding:.375rem}.form-control-color:not(:disabled):not([readonly]){cursor:pointer}.form-control-color::-moz-color-swatch{height:1.5em;border-radius:.25rem}.form-control-color::-webkit-color-swatch{height:1.5em;border-radius:.25rem}.form-select{display:block;width:100%;padding:.375rem 2.25rem .375rem .75rem;-moz-padding-start:calc(0.75rem - 3px);font-size:1rem;font-weight:400;line-height:1.5;color:#212529;background-color:#fff;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right .75rem center;background-size:16px 12px;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-select{transition:none}}.form-select:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-select[multiple],.form-select[size]:not([size="1"]){padding-right:.75rem;background-image:none}.form-select:disabled{background-color:#e9ecef}.form-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #212529}.form-select-sm{padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.form-select-lg{padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.form-check{display:block;min-height:1.5rem;padding-left:1.5em;margin-bottom:.125rem}.form-check .form-check-input{float:left;margin-left:-1.5em}.form-check-input{width:1em;height:1em;margin-top:.25em;vertical-align:top;background-color:#fff;background-repeat:no-repeat;background-position:center;background-size:contain;border:1px solid rgba(0,0,0,.25);-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-print-color-adjust:exact;color-adjust:exact}.form-check-input[type=checkbox]{border-radius:.25em}.form-check-input[type=radio]{border-radius:50%}.form-check-input:active{filter:brightness(90%)}.form-check-input:focus{border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.form-check-input:checked{background-color:#0d6efd;border-color:#0d6efd}.form-check-input:checked[type=checkbox]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e")}.form-check-input:checked[type=radio]{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e")}.form-check-input[type=checkbox]:indeterminate{background-color:#0d6efd;border-color:#0d6efd;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e")}.form-check-input:disabled{pointer-events:none;filter:none;opacity:.5}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{opacity:.5}.form-switch{padding-left:2.5em}.form-switch .form-check-input{width:2em;margin-left:-2.5em;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");background-position:left center;border-radius:2em;transition:background-position .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-switch .form-check-input{transition:none}}.form-switch .form-check-input:focus{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e")}.form-switch .form-check-input:checked{background-position:right center;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.form-check-inline{display:inline-block;margin-right:1rem}.btn-check{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.btn-check:disabled+.btn,.btn-check[disabled]+.btn{pointer-events:none;filter:none;opacity:.65}.form-range{width:100%;height:1.5rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-range:focus{outline:0}.form-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .25rem rgba(13,110,253,.25)}.form-range::-moz-focus-outer{border:0}.form-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#0d6efd;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.form-range::-webkit-slider-thumb:active{background-color:#b6d4fe}.form-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#0d6efd;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.form-range::-moz-range-thumb{-moz-transition:none;transition:none}}.form-range::-moz-range-thumb:active{background-color:#b6d4fe}.form-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.form-range:disabled{pointer-events:none}.form-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.form-range:disabled::-moz-range-thumb{background-color:#adb5bd}.form-floating{position:relative}.form-floating>.form-control,.form-floating>.form-select{height:calc(3.5rem + 2px);line-height:1.25}.form-floating>label{position:absolute;top:0;left:0;height:100%;padding:1rem .75rem;pointer-events:none;border:1px solid transparent;transform-origin:0 0;transition:opacity .1s ease-in-out,transform .1s ease-in-out}@media (prefers-reduced-motion:reduce){.form-floating>label{transition:none}}.form-floating>.form-control{padding:1rem .75rem}.form-floating>.form-control::-moz-placeholder{color:transparent}.form-floating>.form-control::placeholder{color:transparent}.form-floating>.form-control:not(:-moz-placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:focus,.form-floating>.form-control:not(:placeholder-shown){padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:-webkit-autofill{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-select{padding-top:1.625rem;padding-bottom:.625rem}.form-floating>.form-control:not(:-moz-placeholder-shown)~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:focus~label,.form-floating>.form-control:not(:placeholder-shown)~label,.form-floating>.form-select~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.form-floating>.form-control:-webkit-autofill~label{opacity:.65;transform:scale(.85) translateY(-.5rem) translateX(.15rem)}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.form-control,.input-group>.form-select{position:relative;flex:1 1 auto;width:1%;min-width:0}.input-group>.form-control:focus,.input-group>.form-select:focus{z-index:3}.input-group .btn{position:relative;z-index:2}.input-group .btn:focus{z-index:3}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-lg>.btn,.input-group-lg>.form-control,.input-group-lg>.form-select,.input-group-lg>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.input-group-sm>.btn,.input-group-sm>.form-control,.input-group-sm>.form-select,.input-group-sm>.input-group-text{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.input-group-lg>.form-select,.input-group-sm>.form-select{padding-right:3rem}.input-group:not(.has-validation)>.dropdown-toggle:nth-last-child(n+3),.input-group:not(.has-validation)>:not(:last-child):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group.has-validation>.dropdown-toggle:nth-last-child(n+4),.input-group.has-validation>:nth-last-child(n+3):not(.dropdown-toggle):not(.dropdown-menu){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>:not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback){margin-left:-1px;border-top-left-radius:0;border-bottom-left-radius:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#198754}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(25,135,84,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#198754;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-valid,.was-validated .form-select:valid{border-color:#198754}.form-select.is-valid:not([multiple]):not([size]),.form-select.is-valid:not([multiple])[size="1"],.was-validated .form-select:valid:not([multiple]):not([size]),.was-validated .form-select:valid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-valid:focus,.was-validated .form-select:valid:focus{border-color:#198754;box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid,.was-validated .form-check-input:valid{border-color:#198754}.form-check-input.is-valid:checked,.was-validated .form-check-input:valid:checked{background-color:#198754}.form-check-input.is-valid:focus,.was-validated .form-check-input:valid:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#198754}.form-check-inline .form-check-input~.valid-feedback{margin-left:.5em}.input-group .form-control.is-valid,.input-group .form-select.is-valid,.was-validated .input-group .form-control:valid,.was-validated .input-group .form-select:valid{z-index:1}.input-group .form-control.is-valid:focus,.input-group .form-select.is-valid:focus,.was-validated .input-group .form-control:valid:focus,.was-validated .input-group .form-select:valid:focus{z-index:3}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:.875em;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.form-select.is-invalid,.was-validated .form-select:invalid{border-color:#dc3545}.form-select.is-invalid:not([multiple]):not([size]),.form-select.is-invalid:not([multiple])[size="1"],.was-validated .form-select:invalid:not([multiple]):not([size]),.was-validated .form-select:invalid:not([multiple])[size="1"]{padding-right:4.125rem;background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-position:right .75rem center,center right 2.25rem;background-size:16px 12px,calc(.75em + .375rem) calc(.75em + .375rem)}.form-select.is-invalid:focus,.was-validated .form-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid,.was-validated .form-check-input:invalid{border-color:#dc3545}.form-check-input.is-invalid:checked,.was-validated .form-check-input:invalid:checked{background-color:#dc3545}.form-check-input.is-invalid:focus,.was-validated .form-check-input:invalid:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-inline .form-check-input~.invalid-feedback{margin-left:.5em}.input-group .form-control.is-invalid,.input-group .form-select.is-invalid,.was-validated .input-group .form-control:invalid,.was-validated .input-group .form-select:invalid{z-index:2}.input-group .form-control.is-invalid:focus,.input-group .form-select.is-invalid:focus,.was-validated .input-group .form-control:invalid:focus,.was-validated .input-group .form-select:invalid:focus{z-index:3}.btn{display:inline-block;font-weight:400;line-height:1.5;color:#212529;text-align:center;text-decoration:none;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529}.btn-check:focus+.btn,.btn:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.btn.disabled,.btn:disabled,fieldset:disabled .btn{pointer-events:none;opacity:.65}.btn-primary{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-primary:hover{color:#fff;background-color:#0b5ed7;border-color:#0a58ca}.btn-check:focus+.btn-primary,.btn-primary:focus{color:#fff;background-color:#0b5ed7;border-color:#0a58ca;box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-check:active+.btn-primary,.btn-check:checked+.btn-primary,.btn-primary.active,.btn-primary:active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0a58ca;border-color:#0a53be}.btn-check:active+.btn-primary:focus,.btn-check:checked+.btn-primary:focus,.btn-primary.active:focus,.btn-primary:active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(49,132,253,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5c636a;border-color:#565e64}.btn-check:focus+.btn-secondary,.btn-secondary:focus{color:#fff;background-color:#5c636a;border-color:#565e64;box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-check:active+.btn-secondary,.btn-check:checked+.btn-secondary,.btn-secondary.active,.btn-secondary:active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#565e64;border-color:#51585e}.btn-check:active+.btn-secondary:focus,.btn-check:checked+.btn-secondary:focus,.btn-secondary.active:focus,.btn-secondary:active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-success{color:#fff;background-color:#198754;border-color:#198754}.btn-success:hover{color:#fff;background-color:#157347;border-color:#146c43}.btn-check:focus+.btn-success,.btn-success:focus{color:#fff;background-color:#157347;border-color:#146c43;box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-check:active+.btn-success,.btn-check:checked+.btn-success,.btn-success.active,.btn-success:active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#146c43;border-color:#13653f}.btn-check:active+.btn-success:focus,.btn-check:checked+.btn-success:focus,.btn-success.active:focus,.btn-success:active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(60,153,110,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#198754;border-color:#198754}.btn-info{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-info:hover{color:#000;background-color:#31d2f2;border-color:#25cff2}.btn-check:focus+.btn-info,.btn-info:focus{color:#000;background-color:#31d2f2;border-color:#25cff2;box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-check:active+.btn-info,.btn-check:checked+.btn-info,.btn-info.active,.btn-info:active,.show>.btn-info.dropdown-toggle{color:#000;background-color:#3dd5f3;border-color:#25cff2}.btn-check:active+.btn-info:focus,.btn-check:checked+.btn-info:focus,.btn-info.active:focus,.btn-info:active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(11,172,204,.5)}.btn-info.disabled,.btn-info:disabled{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-warning{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#000;background-color:#ffca2c;border-color:#ffc720}.btn-check:focus+.btn-warning,.btn-warning:focus{color:#000;background-color:#ffca2c;border-color:#ffc720;box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-check:active+.btn-warning,.btn-check:checked+.btn-warning,.btn-warning.active,.btn-warning:active,.show>.btn-warning.dropdown-toggle{color:#000;background-color:#ffcd39;border-color:#ffc720}.btn-check:active+.btn-warning:focus,.btn-check:checked+.btn-warning:focus,.btn-warning.active:focus,.btn-warning:active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(217,164,6,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#bb2d3b;border-color:#b02a37}.btn-check:focus+.btn-danger,.btn-danger:focus{color:#fff;background-color:#bb2d3b;border-color:#b02a37;box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-check:active+.btn-danger,.btn-check:checked+.btn-danger,.btn-danger.active,.btn-danger:active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#b02a37;border-color:#a52834}.btn-check:active+.btn-danger:focus,.btn-check:checked+.btn-danger:focus,.btn-danger.active:focus,.btn-danger:active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-light{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:focus+.btn-light,.btn-light:focus{color:#000;background-color:#f9fafb;border-color:#f9fafb;box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-check:active+.btn-light,.btn-check:checked+.btn-light,.btn-light.active,.btn-light:active,.show>.btn-light.dropdown-toggle{color:#000;background-color:#f9fafb;border-color:#f9fafb}.btn-check:active+.btn-light:focus,.btn-check:checked+.btn-light:focus,.btn-light.active:focus,.btn-light:active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(211,212,213,.5)}.btn-light.disabled,.btn-light:disabled{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-dark{color:#fff;background-color:#212529;border-color:#212529}.btn-dark:hover{color:#fff;background-color:#1c1f23;border-color:#1a1e21}.btn-check:focus+.btn-dark,.btn-dark:focus{color:#fff;background-color:#1c1f23;border-color:#1a1e21;box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-check:active+.btn-dark,.btn-check:checked+.btn-dark,.btn-dark.active,.btn-dark:active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1a1e21;border-color:#191c1f}.btn-check:active+.btn-dark:focus,.btn-check:checked+.btn-dark:focus,.btn-dark.active:focus,.btn-dark:active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .25rem rgba(66,70,73,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#212529;border-color:#212529}.btn-outline-primary{color:#0d6efd;border-color:#0d6efd}.btn-outline-primary:hover{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:focus+.btn-outline-primary,.btn-outline-primary:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-check:active+.btn-outline-primary,.btn-check:checked+.btn-outline-primary,.btn-outline-primary.active,.btn-outline-primary.dropdown-toggle.show,.btn-outline-primary:active{color:#fff;background-color:#0d6efd;border-color:#0d6efd}.btn-check:active+.btn-outline-primary:focus,.btn-check:checked+.btn-outline-primary:focus,.btn-outline-primary.active:focus,.btn-outline-primary.dropdown-toggle.show:focus,.btn-outline-primary:active:focus{box-shadow:0 0 0 .25rem rgba(13,110,253,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#0d6efd;background-color:transparent}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:focus+.btn-outline-secondary,.btn-outline-secondary:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-check:active+.btn-outline-secondary,.btn-check:checked+.btn-outline-secondary,.btn-outline-secondary.active,.btn-outline-secondary.dropdown-toggle.show,.btn-outline-secondary:active{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-check:active+.btn-outline-secondary:focus,.btn-check:checked+.btn-outline-secondary:focus,.btn-outline-secondary.active:focus,.btn-outline-secondary.dropdown-toggle.show:focus,.btn-outline-secondary:active:focus{box-shadow:0 0 0 .25rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-success{color:#198754;border-color:#198754}.btn-outline-success:hover{color:#fff;background-color:#198754;border-color:#198754}.btn-check:focus+.btn-outline-success,.btn-outline-success:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-check:active+.btn-outline-success,.btn-check:checked+.btn-outline-success,.btn-outline-success.active,.btn-outline-success.dropdown-toggle.show,.btn-outline-success:active{color:#fff;background-color:#198754;border-color:#198754}.btn-check:active+.btn-outline-success:focus,.btn-check:checked+.btn-outline-success:focus,.btn-outline-success.active:focus,.btn-outline-success.dropdown-toggle.show:focus,.btn-outline-success:active:focus{box-shadow:0 0 0 .25rem rgba(25,135,84,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#198754;background-color:transparent}.btn-outline-info{color:#0dcaf0;border-color:#0dcaf0}.btn-outline-info:hover{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:focus+.btn-outline-info,.btn-outline-info:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-check:active+.btn-outline-info,.btn-check:checked+.btn-outline-info,.btn-outline-info.active,.btn-outline-info.dropdown-toggle.show,.btn-outline-info:active{color:#000;background-color:#0dcaf0;border-color:#0dcaf0}.btn-check:active+.btn-outline-info:focus,.btn-check:checked+.btn-outline-info:focus,.btn-outline-info.active:focus,.btn-outline-info.dropdown-toggle.show:focus,.btn-outline-info:active:focus{box-shadow:0 0 0 .25rem rgba(13,202,240,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#0dcaf0;background-color:transparent}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:focus+.btn-outline-warning,.btn-outline-warning:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-check:active+.btn-outline-warning,.btn-check:checked+.btn-outline-warning,.btn-outline-warning.active,.btn-outline-warning.dropdown-toggle.show,.btn-outline-warning:active{color:#000;background-color:#ffc107;border-color:#ffc107}.btn-check:active+.btn-outline-warning:focus,.btn-check:checked+.btn-outline-warning:focus,.btn-outline-warning.active:focus,.btn-outline-warning.dropdown-toggle.show:focus,.btn-outline-warning:active:focus{box-shadow:0 0 0 .25rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:focus+.btn-outline-danger,.btn-outline-danger:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-check:active+.btn-outline-danger,.btn-check:checked+.btn-outline-danger,.btn-outline-danger.active,.btn-outline-danger.dropdown-toggle.show,.btn-outline-danger:active{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-check:active+.btn-outline-danger:focus,.btn-check:checked+.btn-outline-danger:focus,.btn-outline-danger.active:focus,.btn-outline-danger.dropdown-toggle.show:focus,.btn-outline-danger:active:focus{box-shadow:0 0 0 .25rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:focus+.btn-outline-light,.btn-outline-light:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-check:active+.btn-outline-light,.btn-check:checked+.btn-outline-light,.btn-outline-light.active,.btn-outline-light.dropdown-toggle.show,.btn-outline-light:active{color:#000;background-color:#f8f9fa;border-color:#f8f9fa}.btn-check:active+.btn-outline-light:focus,.btn-check:checked+.btn-outline-light:focus,.btn-outline-light.active:focus,.btn-outline-light.dropdown-toggle.show:focus,.btn-outline-light:active:focus{box-shadow:0 0 0 .25rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-dark{color:#212529;border-color:#212529}.btn-outline-dark:hover{color:#fff;background-color:#212529;border-color:#212529}.btn-check:focus+.btn-outline-dark,.btn-outline-dark:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-check:active+.btn-outline-dark,.btn-check:checked+.btn-outline-dark,.btn-outline-dark.active,.btn-outline-dark.dropdown-toggle.show,.btn-outline-dark:active{color:#fff;background-color:#212529;border-color:#212529}.btn-check:active+.btn-outline-dark:focus,.btn-check:checked+.btn-outline-dark:focus,.btn-outline-dark.active:focus,.btn-outline-dark.dropdown-toggle.show:focus,.btn-outline-dark:active:focus{box-shadow:0 0 0 .25rem rgba(33,37,41,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#212529;background-color:transparent}.btn-link{font-weight:400;color:#0d6efd;text-decoration:underline}.btn-link:hover{color:#0a58ca}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;border-radius:.2rem}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropend,.dropstart,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;z-index:1000;display:none;min-width:10rem;padding:.5rem 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu[data-bs-popper]{top:100%;left:0;margin-top:.125rem}.dropdown-menu-start{--bs-position:start}.dropdown-menu-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-end{--bs-position:end}.dropdown-menu-end[data-bs-popper]{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-start{--bs-position:start}.dropdown-menu-sm-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-sm-end{--bs-position:end}.dropdown-menu-sm-end[data-bs-popper]{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-start{--bs-position:start}.dropdown-menu-md-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-md-end{--bs-position:end}.dropdown-menu-md-end[data-bs-popper]{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-start{--bs-position:start}.dropdown-menu-lg-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-lg-end{--bs-position:end}.dropdown-menu-lg-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-start{--bs-position:start}.dropdown-menu-xl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xl-end{--bs-position:end}.dropdown-menu-xl-end[data-bs-popper]{right:0;left:auto}}@media (min-width:1400px){.dropdown-menu-xxl-start{--bs-position:start}.dropdown-menu-xxl-start[data-bs-popper]{right:auto;left:0}.dropdown-menu-xxl-end{--bs-position:end}.dropdown-menu-xxl-end[data-bs-popper]{right:0;left:auto}}.dropup .dropdown-menu[data-bs-popper]{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-menu[data-bs-popper]{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropend .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropend .dropdown-toggle:empty::after{margin-left:0}.dropend .dropdown-toggle::after{vertical-align:0}.dropstart .dropdown-menu[data-bs-popper]{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropstart .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropstart .dropdown-toggle::after{display:none}.dropstart .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropstart .dropdown-toggle:empty::after{margin-left:0}.dropstart .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid rgba(0,0,0,.15)}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;text-decoration:none;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#1e2125;background-color:#e9ecef}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#0d6efd}.dropdown-item.disabled,.dropdown-item:disabled{color:#adb5bd;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.dropdown-menu-dark{color:#dee2e6;background-color:#343a40;border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item{color:#dee2e6}.dropdown-menu-dark .dropdown-item:focus,.dropdown-menu-dark .dropdown-item:hover{color:#fff;background-color:rgba(255,255,255,.15)}.dropdown-menu-dark .dropdown-item.active,.dropdown-menu-dark .dropdown-item:active{color:#fff;background-color:#0d6efd}.dropdown-menu-dark .dropdown-item.disabled,.dropdown-menu-dark .dropdown-item:disabled{color:#adb5bd}.dropdown-menu-dark .dropdown-divider{border-color:rgba(0,0,0,.15)}.dropdown-menu-dark .dropdown-item-text{color:#dee2e6}.dropdown-menu-dark .dropdown-header{color:#adb5bd}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn-check:checked+.btn,.btn-group-vertical>.btn-check:focus+.btn,.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn-check:checked+.btn,.btn-group>.btn-check:focus+.btn,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:nth-child(n+3),.btn-group>:not(.btn-check)+.btn{border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropend .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropstart .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn~.btn{border-top-left-radius:0;border-top-right-radius:0}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem;color:#0d6efd;text-decoration:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-link{transition:none}}.nav-link:focus,.nav-link:hover{color:#0a58ca}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-link{margin-bottom:-1px;background:0 0;border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6;isolation:isolate}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{background:0 0;border:0;border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#0d6efd}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.nav-fill .nav-item .nav-link,.nav-justified .nav-item .nav-link{width:100%}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;padding-top:.5rem;padding-bottom:.5rem}.navbar>.container,.navbar>.container-fluid,.navbar>.container-lg,.navbar>.container-md,.navbar>.container-sm,.navbar>.container-xl,.navbar>.container-xxl{display:flex;flex-wrap:inherit;align-items:center;justify-content:space-between}.navbar-brand{padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;text-decoration:none;white-space:nowrap}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static}.navbar-text{padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem;transition:box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.navbar-toggler{transition:none}}.navbar-toggler:hover{text-decoration:none}.navbar-toggler:focus{text-decoration:none;outline:0;box-shadow:0 0 0 .25rem}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;background-repeat:no-repeat;background-position:center;background-size:100%}.navbar-nav-scroll{max-height:var(--bs-scroll-height,75vh);overflow-y:auto}@media (min-width:576px){.navbar-expand-sm{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm .navbar-nav-scroll{overflow:visible}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (min-width:768px){.navbar-expand-md{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md .navbar-nav-scroll{overflow:visible}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (min-width:992px){.navbar-expand-lg{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg .navbar-nav-scroll{overflow:visible}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (min-width:1200px){.navbar-expand-xl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl .navbar-nav-scroll{overflow:visible}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}@media (min-width:1400px){.navbar-expand-xxl{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand-xxl .navbar-nav{flex-direction:row}.navbar-expand-xxl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xxl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xxl .navbar-nav-scroll{overflow:visible}.navbar-expand-xxl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xxl .navbar-toggler{display:none}}.navbar-expand{flex-wrap:nowrap;justify-content:flex-start}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand .navbar-nav-scroll{overflow:visible}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.55)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.55);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.55)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.55)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.55);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.55)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;padding:1rem 1rem}.card-title{margin-bottom:.5rem}.card-subtitle{margin-top:-.25rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1rem}.card-header{padding:.5rem 1rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.5rem 1rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.5rem;margin-bottom:-.5rem;margin-left:-.5rem;border-bottom:0}.card-header-pills{margin-right:-.5rem;margin-left:-.5rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-group>.card{margin-bottom:.75rem}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.accordion-button{position:relative;display:flex;align-items:center;width:100%;padding:1rem 1.25rem;font-size:1rem;color:#212529;text-align:left;background-color:#fff;border:0;border-radius:0;overflow-anchor:none;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,border-radius .15s ease}@media (prefers-reduced-motion:reduce){.accordion-button{transition:none}}.accordion-button:not(.collapsed){color:#0c63e4;background-color:#e7f1ff;box-shadow:inset 0 -1px 0 rgba(0,0,0,.125)}.accordion-button:not(.collapsed)::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");transform:rotate(-180deg)}.accordion-button::after{flex-shrink:0;width:1.25rem;height:1.25rem;margin-left:auto;content:"";background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-size:1.25rem;transition:transform .2s ease-in-out}@media (prefers-reduced-motion:reduce){.accordion-button::after{transition:none}}.accordion-button:hover{z-index:2}.accordion-button:focus{z-index:3;border-color:#86b7fe;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.accordion-header{margin-bottom:0}.accordion-item{background-color:#fff;border:1px solid rgba(0,0,0,.125)}.accordion-item:first-of-type{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.accordion-item:first-of-type .accordion-button{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.accordion-item:not(:first-of-type){border-top:0}.accordion-item:last-of-type{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-item:last-of-type .accordion-button.collapsed{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.accordion-item:last-of-type .accordion-collapse{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.accordion-body{padding:1rem 1.25rem}.accordion-flush .accordion-collapse{border-width:0}.accordion-flush .accordion-item{border-right:0;border-left:0;border-radius:0}.accordion-flush .accordion-item:first-child{border-top:0}.accordion-flush .accordion-item:last-child{border-bottom:0}.accordion-flush .accordion-item .accordion-button{border-radius:0}.breadcrumb{display:flex;flex-wrap:wrap;padding:0 0;margin-bottom:1rem;list-style:none}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{float:left;padding-right:.5rem;color:#6c757d;content:var(--bs-breadcrumb-divider, "/")}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none}.page-link{position:relative;display:block;color:#0d6efd;text-decoration:none;background-color:#fff;border:1px solid #dee2e6;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.page-link{transition:none}}.page-link:hover{z-index:2;color:#0a58ca;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;color:#0a58ca;background-color:#e9ecef;outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)}.page-item:not(:first-child) .page-link{margin-left:-1px}.page-item.active .page-link{z-index:3;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;background-color:#fff;border-color:#dee2e6}.page-link{padding:.375rem .75rem}.page-item:first-child .page-link{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.35em .65em;font-size:.75em;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.alert{position:relative;padding:1rem 1rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:3rem}.alert-dismissible .btn-close{position:absolute;top:0;right:0;z-index:2;padding:1.25rem 1rem}.alert-primary{color:#084298;background-color:#cfe2ff;border-color:#b6d4fe}.alert-primary .alert-link{color:#06357a}.alert-secondary{color:#41464b;background-color:#e2e3e5;border-color:#d3d6d8}.alert-secondary .alert-link{color:#34383c}.alert-success{color:#0f5132;background-color:#d1e7dd;border-color:#badbcc}.alert-success .alert-link{color:#0c4128}.alert-info{color:#055160;background-color:#cff4fc;border-color:#b6effb}.alert-info .alert-link{color:#04414d}.alert-warning{color:#664d03;background-color:#fff3cd;border-color:#ffecb5}.alert-warning .alert-link{color:#523e02}.alert-danger{color:#842029;background-color:#f8d7da;border-color:#f5c2c7}.alert-danger .alert-link{color:#6a1a21}.alert-light{color:#636464;background-color:#fefefe;border-color:#fdfdfe}.alert-light .alert-link{color:#4f5050}.alert-dark{color:#141619;background-color:#d3d3d4;border-color:#bcbebf}.alert-dark .alert-link{color:#101214}@-webkit-keyframes progress-bar-stripes{0%{background-position-x:1rem}}@keyframes progress-bar-stripes{0%{background-position-x:1rem}}.progress{display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:flex;flex-direction:column;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#0d6efd;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:1s linear infinite progress-bar-stripes;animation:1s linear infinite progress-bar-stripes}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-numbered{list-style-type:none;counter-reset:section}.list-group-numbered>li::before{content:counters(section, ".") ". ";counter-increment:section}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.5rem 1rem;color:#212529;text-decoration:none;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#0d6efd;border-color:#0d6efd}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1400px){.list-group-horizontal-xxl{flex-direction:row}.list-group-horizontal-xxl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xxl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xxl>.list-group-item.active{margin-top:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xxl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#084298;background-color:#cfe2ff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#084298;background-color:#bacbe6}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#084298;border-color:#084298}.list-group-item-secondary{color:#41464b;background-color:#e2e3e5}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#41464b;background-color:#cbccce}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#41464b;border-color:#41464b}.list-group-item-success{color:#0f5132;background-color:#d1e7dd}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#0f5132;background-color:#bcd0c7}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#0f5132;border-color:#0f5132}.list-group-item-info{color:#055160;background-color:#cff4fc}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#055160;background-color:#badce3}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#055160;border-color:#055160}.list-group-item-warning{color:#664d03;background-color:#fff3cd}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#664d03;background-color:#e6dbb9}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#664d03;border-color:#664d03}.list-group-item-danger{color:#842029;background-color:#f8d7da}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#842029;background-color:#dfc2c4}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#842029;border-color:#842029}.list-group-item-light{color:#636464;background-color:#fefefe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#636464;background-color:#e5e5e5}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#636464;border-color:#636464}.list-group-item-dark{color:#141619;background-color:#d3d3d4}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#141619;background-color:#bebebf}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#141619;border-color:#141619}.btn-close{box-sizing:content-box;width:1em;height:1em;padding:.25em .25em;color:#000;background:transparent url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e") center/1em auto no-repeat;border:0;border-radius:.25rem;opacity:.5}.btn-close:hover{color:#000;text-decoration:none;opacity:.75}.btn-close:focus{outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25);opacity:1}.btn-close.disabled,.btn-close:disabled{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;opacity:.25}.btn-close-white{filter:invert(1) grayscale(100%) brightness(200%)}.toast{width:350px;max-width:100%;font-size:.875rem;pointer-events:auto;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .5rem 1rem rgba(0,0,0,.15);border-radius:.25rem}.toast:not(.showing):not(.show){opacity:0}.toast.hide{display:none}.toast-container{width:-webkit-max-content;width:-moz-max-content;width:max-content;max-width:100%;pointer-events:none}.toast-container>:not(:last-child){margin-bottom:.75rem}.toast-header{display:flex;align-items:center;padding:.5rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-header .btn-close{margin-right:-.375rem;margin-left:.75rem}.toast-body{padding:.75rem;word-wrap:break-word}.modal{position:fixed;top:0;left:0;z-index:1060;display:none;width:100%;height:100%;overflow-x:hidden;overflow-y:auto;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:100%;overflow:hidden}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;flex-shrink:0;align-items:center;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .btn-close{padding:.5rem .5rem;margin:-.5rem -.5rem -.5rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;flex-shrink:0;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{height:calc(100% - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.modal-fullscreen{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen .modal-header{border-radius:0}.modal-fullscreen .modal-body{overflow-y:auto}.modal-fullscreen .modal-footer{border-radius:0}@media (max-width:575.98px){.modal-fullscreen-sm-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-sm-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-sm-down .modal-header{border-radius:0}.modal-fullscreen-sm-down .modal-body{overflow-y:auto}.modal-fullscreen-sm-down .modal-footer{border-radius:0}}@media (max-width:767.98px){.modal-fullscreen-md-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-md-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-md-down .modal-header{border-radius:0}.modal-fullscreen-md-down .modal-body{overflow-y:auto}.modal-fullscreen-md-down .modal-footer{border-radius:0}}@media (max-width:991.98px){.modal-fullscreen-lg-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-lg-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-lg-down .modal-header{border-radius:0}.modal-fullscreen-lg-down .modal-body{overflow-y:auto}.modal-fullscreen-lg-down .modal-footer{border-radius:0}}@media (max-width:1199.98px){.modal-fullscreen-xl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xl-down .modal-header{border-radius:0}.modal-fullscreen-xl-down .modal-body{overflow-y:auto}.modal-fullscreen-xl-down .modal-footer{border-radius:0}}@media (max-width:1399.98px){.modal-fullscreen-xxl-down{width:100vw;max-width:none;height:100%;margin:0}.modal-fullscreen-xxl-down .modal-content{height:100%;border:0;border-radius:0}.modal-fullscreen-xxl-down .modal-header{border-radius:0}.modal-fullscreen-xxl-down .modal-body{overflow-y:auto}.modal-fullscreen-xxl-down .modal-footer{border-radius:0}}.tooltip{position:absolute;z-index:1080;display:block;margin:0;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .tooltip-arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .tooltip-arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[data-popper-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow,.bs-tooltip-top .tooltip-arrow{bottom:0}.bs-tooltip-auto[data-popper-placement^=top] .tooltip-arrow::before,.bs-tooltip-top .tooltip-arrow::before{top:-1px;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[data-popper-placement^=right],.bs-tooltip-end{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow,.bs-tooltip-end .tooltip-arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=right] .tooltip-arrow::before,.bs-tooltip-end .tooltip-arrow::before{right:-1px;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[data-popper-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow,.bs-tooltip-bottom .tooltip-arrow{top:0}.bs-tooltip-auto[data-popper-placement^=bottom] .tooltip-arrow::before,.bs-tooltip-bottom .tooltip-arrow::before{bottom:-1px;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[data-popper-placement^=left],.bs-tooltip-start{padding:0 .4rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow,.bs-tooltip-start .tooltip-arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[data-popper-placement^=left] .tooltip-arrow::before,.bs-tooltip-start .tooltip-arrow::before{left:-1px;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1070;display:block;max-width:276px;font-family:var(--bs-font-sans-serif);font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .popover-arrow{position:absolute;display:block;width:1rem;height:.5rem}.popover .popover-arrow::after,.popover .popover-arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow,.bs-popover-top>.popover-arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::before,.bs-popover-top>.popover-arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=top]>.popover-arrow::after,.bs-popover-top>.popover-arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow,.bs-popover-end>.popover-arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::before,.bs-popover-end>.popover-arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=right]>.popover-arrow::after,.bs-popover-end>.popover-arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow,.bs-popover-bottom>.popover-arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::before,.bs-popover-bottom>.popover-arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=bottom]>.popover-arrow::after,.bs-popover-bottom>.popover-arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[data-popper-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f0f0f0}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow,.bs-popover-start>.popover-arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::before,.bs-popover-start>.popover-arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[data-popper-placement^=left]>.popover-arrow::after,.bs-popover-start>.popover-arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem 1rem;margin-bottom:0;font-size:1rem;background-color:#f0f0f0;border-bottom:1px solid rgba(0,0,0,.2);border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:1rem 1rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-end,.carousel-item-next:not(.carousel-item-start){transform:translateX(100%)}.active.carousel-item-start,.carousel-item-prev:not(.carousel-item-end){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-start,.carousel-fade .carousel-item-prev.carousel-item-end,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-end,.carousel-fade .active.carousel-item-start{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;padding:0;color:#fff;text-align:center;background:0 0;border:0;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:2rem;height:2rem;background-repeat:no-repeat;background-position:50%;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:2;display:flex;justify-content:center;padding:0;margin-right:15%;margin-bottom:1rem;margin-left:15%;list-style:none}.carousel-indicators [data-bs-target]{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;padding:0;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border:0;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators [data-bs-target]{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:1.25rem;left:15%;padding-top:1.25rem;padding-bottom:1.25rem;color:#fff;text-align:center}.carousel-dark .carousel-control-next-icon,.carousel-dark .carousel-control-prev-icon{filter:invert(1) grayscale(100)}.carousel-dark .carousel-indicators [data-bs-target]{background-color:#000}.carousel-dark .carousel-caption{color:#000}@-webkit-keyframes spinner-border{to{transform:rotate(360deg)}}@keyframes spinner-border{to{transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:.75s linear infinite spinner-border;animation:.75s linear infinite spinner-border}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:-.125em;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:.75s linear infinite spinner-grow;animation:.75s linear infinite spinner-grow}.spinner-grow-sm{width:1rem;height:1rem}@media (prefers-reduced-motion:reduce){.spinner-border,.spinner-grow{-webkit-animation-duration:1.5s;animation-duration:1.5s}}.offcanvas{position:fixed;bottom:0;z-index:1050;display:flex;flex-direction:column;max-width:100%;visibility:hidden;background-color:#fff;background-clip:padding-box;outline:0;transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.offcanvas{transition:none}}.offcanvas-header{display:flex;align-items:center;justify-content:space-between;padding:1rem 1rem}.offcanvas-header .btn-close{padding:.5rem .5rem;margin-top:-.5rem;margin-right:-.5rem;margin-bottom:-.5rem}.offcanvas-title{margin-bottom:0;line-height:1.5}.offcanvas-body{flex-grow:1;padding:1rem 1rem;overflow-y:auto}.offcanvas-start{top:0;left:0;width:400px;border-right:1px solid rgba(0,0,0,.2);transform:translateX(-100%)}.offcanvas-end{top:0;right:0;width:400px;border-left:1px solid rgba(0,0,0,.2);transform:translateX(100%)}.offcanvas-top{top:0;right:0;left:0;height:30vh;max-height:100%;border-bottom:1px solid rgba(0,0,0,.2);transform:translateY(-100%)}.offcanvas-bottom{right:0;left:0;height:30vh;max-height:100%;border-top:1px solid rgba(0,0,0,.2);transform:translateY(100%)}.offcanvas.show{transform:none}.clearfix::after{display:block;clear:both;content:""}.link-primary{color:#0d6efd}.link-primary:focus,.link-primary:hover{color:#0a58ca}.link-secondary{color:#6c757d}.link-secondary:focus,.link-secondary:hover{color:#565e64}.link-success{color:#198754}.link-success:focus,.link-success:hover{color:#146c43}.link-info{color:#0dcaf0}.link-info:focus,.link-info:hover{color:#3dd5f3}.link-warning{color:#ffc107}.link-warning:focus,.link-warning:hover{color:#ffcd39}.link-danger{color:#dc3545}.link-danger:focus,.link-danger:hover{color:#b02a37}.link-light{color:#f8f9fa}.link-light:focus,.link-light:hover{color:#f9fafb}.link-dark{color:#212529}.link-dark:focus,.link-dark:hover{color:#1a1e21}.ratio{position:relative;width:100%}.ratio::before{display:block;padding-top:var(--bs-aspect-ratio);content:""}.ratio>*{position:absolute;top:0;left:0;width:100%;height:100%}.ratio-1x1{--bs-aspect-ratio:100%}.ratio-4x3{--bs-aspect-ratio:calc(3 / 4 * 100%)}.ratio-16x9{--bs-aspect-ratio:calc(9 / 16 * 100%)}.ratio-21x9{--bs-aspect-ratio:calc(9 / 21 * 100%)}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}@media (min-width:576px){.sticky-sm-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:768px){.sticky-md-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:992px){.sticky-lg-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1200px){.sticky-xl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}@media (min-width:1400px){.sticky-xxl-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.visually-hidden,.visually-hidden-focusable:not(:focus):not(:focus-within){position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;content:""}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.float-start{float:left!important}.float-end{float:right!important}.float-none{float:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.overflow-visible{overflow:visible!important}.overflow-scroll{overflow:scroll!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-grid{display:grid!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}.d-none{display:none!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.top-0{top:0!important}.top-50{top:50%!important}.top-100{top:100%!important}.bottom-0{bottom:0!important}.bottom-50{bottom:50%!important}.bottom-100{bottom:100%!important}.start-0{left:0!important}.start-50{left:50%!important}.start-100{left:100%!important}.end-0{right:0!important}.end-50{right:50%!important}.end-100{right:100%!important}.translate-middle{transform:translate(-50%,-50%)!important}.translate-middle-x{transform:translateX(-50%)!important}.translate-middle-y{transform:translateY(-50%)!important}.border{border:1px solid #dee2e6!important}.border-0{border:0!important}.border-top{border-top:1px solid #dee2e6!important}.border-top-0{border-top:0!important}.border-end{border-right:1px solid #dee2e6!important}.border-end-0{border-right:0!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-bottom-0{border-bottom:0!important}.border-start{border-left:1px solid #dee2e6!important}.border-start-0{border-left:0!important}.border-primary{border-color:#0d6efd!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#198754!important}.border-info{border-color:#0dcaf0!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#212529!important}.border-white{border-color:#fff!important}.border-1{border-width:1px!important}.border-2{border-width:2px!important}.border-3{border-width:3px!important}.border-4{border-width:4px!important}.border-5{border-width:5px!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.mw-100{max-width:100%!important}.vw-100{width:100vw!important}.min-vw-100{min-width:100vw!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mh-100{max-height:100%!important}.vh-100{height:100vh!important}.min-vh-100{min-height:100vh!important}.flex-fill{flex:1 1 auto!important}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-0{gap:0!important}.gap-1{gap:.25rem!important}.gap-2{gap:.5rem!important}.gap-3{gap:1rem!important}.gap-4{gap:1.5rem!important}.gap-5{gap:3rem!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.justify-content-evenly{justify-content:space-evenly!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}.order-first{order:-1!important}.order-0{order:0!important}.order-1{order:1!important}.order-2{order:2!important}.order-3{order:3!important}.order-4{order:4!important}.order-5{order:5!important}.order-last{order:6!important}.m-0{margin:0!important}.m-1{margin:.25rem!important}.m-2{margin:.5rem!important}.m-3{margin:1rem!important}.m-4{margin:1.5rem!important}.m-5{margin:3rem!important}.m-auto{margin:auto!important}.mx-0{margin-right:0!important;margin-left:0!important}.mx-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-3{margin-right:1rem!important;margin-left:1rem!important}.mx-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-5{margin-right:3rem!important;margin-left:3rem!important}.mx-auto{margin-right:auto!important;margin-left:auto!important}.my-0{margin-top:0!important;margin-bottom:0!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-0{margin-top:0!important}.mt-1{margin-top:.25rem!important}.mt-2{margin-top:.5rem!important}.mt-3{margin-top:1rem!important}.mt-4{margin-top:1.5rem!important}.mt-5{margin-top:3rem!important}.mt-auto{margin-top:auto!important}.me-0{margin-right:0!important}.me-1{margin-right:.25rem!important}.me-2{margin-right:.5rem!important}.me-3{margin-right:1rem!important}.me-4{margin-right:1.5rem!important}.me-5{margin-right:3rem!important}.me-auto{margin-right:auto!important}.mb-0{margin-bottom:0!important}.mb-1{margin-bottom:.25rem!important}.mb-2{margin-bottom:.5rem!important}.mb-3{margin-bottom:1rem!important}.mb-4{margin-bottom:1.5rem!important}.mb-5{margin-bottom:3rem!important}.mb-auto{margin-bottom:auto!important}.ms-0{margin-left:0!important}.ms-1{margin-left:.25rem!important}.ms-2{margin-left:.5rem!important}.ms-3{margin-left:1rem!important}.ms-4{margin-left:1.5rem!important}.ms-5{margin-left:3rem!important}.ms-auto{margin-left:auto!important}.p-0{padding:0!important}.p-1{padding:.25rem!important}.p-2{padding:.5rem!important}.p-3{padding:1rem!important}.p-4{padding:1.5rem!important}.p-5{padding:3rem!important}.px-0{padding-right:0!important;padding-left:0!important}.px-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-3{padding-right:1rem!important;padding-left:1rem!important}.px-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-5{padding-right:3rem!important;padding-left:3rem!important}.py-0{padding-top:0!important;padding-bottom:0!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-0{padding-top:0!important}.pt-1{padding-top:.25rem!important}.pt-2{padding-top:.5rem!important}.pt-3{padding-top:1rem!important}.pt-4{padding-top:1.5rem!important}.pt-5{padding-top:3rem!important}.pe-0{padding-right:0!important}.pe-1{padding-right:.25rem!important}.pe-2{padding-right:.5rem!important}.pe-3{padding-right:1rem!important}.pe-4{padding-right:1.5rem!important}.pe-5{padding-right:3rem!important}.pb-0{padding-bottom:0!important}.pb-1{padding-bottom:.25rem!important}.pb-2{padding-bottom:.5rem!important}.pb-3{padding-bottom:1rem!important}.pb-4{padding-bottom:1.5rem!important}.pb-5{padding-bottom:3rem!important}.ps-0{padding-left:0!important}.ps-1{padding-left:.25rem!important}.ps-2{padding-left:.5rem!important}.ps-3{padding-left:1rem!important}.ps-4{padding-left:1.5rem!important}.ps-5{padding-left:3rem!important}.font-monospace{font-family:var(--bs-font-monospace)!important}.fs-1{font-size:calc(1.375rem + 1.5vw)!important}.fs-2{font-size:calc(1.325rem + .9vw)!important}.fs-3{font-size:calc(1.3rem + .6vw)!important}.fs-4{font-size:calc(1.275rem + .3vw)!important}.fs-5{font-size:1.25rem!important}.fs-6{font-size:1rem!important}.fst-italic{font-style:italic!important}.fst-normal{font-style:normal!important}.fw-light{font-weight:300!important}.fw-lighter{font-weight:lighter!important}.fw-normal{font-weight:400!important}.fw-bold{font-weight:700!important}.fw-bolder{font-weight:bolder!important}.lh-1{line-height:1!important}.lh-sm{line-height:1.25!important}.lh-base{line-height:1.5!important}.lh-lg{line-height:2!important}.text-start{text-align:left!important}.text-end{text-align:right!important}.text-center{text-align:center!important}.text-decoration-none{text-decoration:none!important}.text-decoration-underline{text-decoration:underline!important}.text-decoration-line-through{text-decoration:line-through!important}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-break{word-wrap:break-word!important;word-break:break-word!important}.text-primary{color:#0d6efd!important}.text-secondary{color:#6c757d!important}.text-success{color:#198754!important}.text-info{color:#0dcaf0!important}.text-warning{color:#ffc107!important}.text-danger{color:#dc3545!important}.text-light{color:#f8f9fa!important}.text-dark{color:#212529!important}.text-white{color:#fff!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-reset{color:inherit!important}.bg-primary{background-color:#0d6efd!important}.bg-secondary{background-color:#6c757d!important}.bg-success{background-color:#198754!important}.bg-info{background-color:#0dcaf0!important}.bg-warning{background-color:#ffc107!important}.bg-danger{background-color:#dc3545!important}.bg-light{background-color:#f8f9fa!important}.bg-dark{background-color:#212529!important}.bg-body{background-color:#fff!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.bg-gradient{background-image:var(--bs-gradient)!important}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important}.pe-none{pointer-events:none!important}.pe-auto{pointer-events:auto!important}.rounded{border-radius:.25rem!important}.rounded-0{border-radius:0!important}.rounded-1{border-radius:.2rem!important}.rounded-2{border-radius:.25rem!important}.rounded-3{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-end{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-start{border-bottom-left-radius:.25rem!important;border-top-left-radius:.25rem!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media (min-width:576px){.float-sm-start{float:left!important}.float-sm-end{float:right!important}.float-sm-none{float:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-grid{display:grid!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}.d-sm-none{display:none!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-sm-0{gap:0!important}.gap-sm-1{gap:.25rem!important}.gap-sm-2{gap:.5rem!important}.gap-sm-3{gap:1rem!important}.gap-sm-4{gap:1.5rem!important}.gap-sm-5{gap:3rem!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.justify-content-sm-evenly{justify-content:space-evenly!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}.order-sm-first{order:-1!important}.order-sm-0{order:0!important}.order-sm-1{order:1!important}.order-sm-2{order:2!important}.order-sm-3{order:3!important}.order-sm-4{order:4!important}.order-sm-5{order:5!important}.order-sm-last{order:6!important}.m-sm-0{margin:0!important}.m-sm-1{margin:.25rem!important}.m-sm-2{margin:.5rem!important}.m-sm-3{margin:1rem!important}.m-sm-4{margin:1.5rem!important}.m-sm-5{margin:3rem!important}.m-sm-auto{margin:auto!important}.mx-sm-0{margin-right:0!important;margin-left:0!important}.mx-sm-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-sm-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-sm-3{margin-right:1rem!important;margin-left:1rem!important}.mx-sm-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-sm-5{margin-right:3rem!important;margin-left:3rem!important}.mx-sm-auto{margin-right:auto!important;margin-left:auto!important}.my-sm-0{margin-top:0!important;margin-bottom:0!important}.my-sm-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-sm-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-sm-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-sm-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-sm-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-sm-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-sm-0{margin-top:0!important}.mt-sm-1{margin-top:.25rem!important}.mt-sm-2{margin-top:.5rem!important}.mt-sm-3{margin-top:1rem!important}.mt-sm-4{margin-top:1.5rem!important}.mt-sm-5{margin-top:3rem!important}.mt-sm-auto{margin-top:auto!important}.me-sm-0{margin-right:0!important}.me-sm-1{margin-right:.25rem!important}.me-sm-2{margin-right:.5rem!important}.me-sm-3{margin-right:1rem!important}.me-sm-4{margin-right:1.5rem!important}.me-sm-5{margin-right:3rem!important}.me-sm-auto{margin-right:auto!important}.mb-sm-0{margin-bottom:0!important}.mb-sm-1{margin-bottom:.25rem!important}.mb-sm-2{margin-bottom:.5rem!important}.mb-sm-3{margin-bottom:1rem!important}.mb-sm-4{margin-bottom:1.5rem!important}.mb-sm-5{margin-bottom:3rem!important}.mb-sm-auto{margin-bottom:auto!important}.ms-sm-0{margin-left:0!important}.ms-sm-1{margin-left:.25rem!important}.ms-sm-2{margin-left:.5rem!important}.ms-sm-3{margin-left:1rem!important}.ms-sm-4{margin-left:1.5rem!important}.ms-sm-5{margin-left:3rem!important}.ms-sm-auto{margin-left:auto!important}.p-sm-0{padding:0!important}.p-sm-1{padding:.25rem!important}.p-sm-2{padding:.5rem!important}.p-sm-3{padding:1rem!important}.p-sm-4{padding:1.5rem!important}.p-sm-5{padding:3rem!important}.px-sm-0{padding-right:0!important;padding-left:0!important}.px-sm-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-sm-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-sm-3{padding-right:1rem!important;padding-left:1rem!important}.px-sm-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-sm-5{padding-right:3rem!important;padding-left:3rem!important}.py-sm-0{padding-top:0!important;padding-bottom:0!important}.py-sm-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-sm-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-sm-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-sm-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-sm-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-sm-0{padding-top:0!important}.pt-sm-1{padding-top:.25rem!important}.pt-sm-2{padding-top:.5rem!important}.pt-sm-3{padding-top:1rem!important}.pt-sm-4{padding-top:1.5rem!important}.pt-sm-5{padding-top:3rem!important}.pe-sm-0{padding-right:0!important}.pe-sm-1{padding-right:.25rem!important}.pe-sm-2{padding-right:.5rem!important}.pe-sm-3{padding-right:1rem!important}.pe-sm-4{padding-right:1.5rem!important}.pe-sm-5{padding-right:3rem!important}.pb-sm-0{padding-bottom:0!important}.pb-sm-1{padding-bottom:.25rem!important}.pb-sm-2{padding-bottom:.5rem!important}.pb-sm-3{padding-bottom:1rem!important}.pb-sm-4{padding-bottom:1.5rem!important}.pb-sm-5{padding-bottom:3rem!important}.ps-sm-0{padding-left:0!important}.ps-sm-1{padding-left:.25rem!important}.ps-sm-2{padding-left:.5rem!important}.ps-sm-3{padding-left:1rem!important}.ps-sm-4{padding-left:1.5rem!important}.ps-sm-5{padding-left:3rem!important}.text-sm-start{text-align:left!important}.text-sm-end{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.float-md-start{float:left!important}.float-md-end{float:right!important}.float-md-none{float:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-grid{display:grid!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}.d-md-none{display:none!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-md-0{gap:0!important}.gap-md-1{gap:.25rem!important}.gap-md-2{gap:.5rem!important}.gap-md-3{gap:1rem!important}.gap-md-4{gap:1.5rem!important}.gap-md-5{gap:3rem!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.justify-content-md-evenly{justify-content:space-evenly!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}.order-md-first{order:-1!important}.order-md-0{order:0!important}.order-md-1{order:1!important}.order-md-2{order:2!important}.order-md-3{order:3!important}.order-md-4{order:4!important}.order-md-5{order:5!important}.order-md-last{order:6!important}.m-md-0{margin:0!important}.m-md-1{margin:.25rem!important}.m-md-2{margin:.5rem!important}.m-md-3{margin:1rem!important}.m-md-4{margin:1.5rem!important}.m-md-5{margin:3rem!important}.m-md-auto{margin:auto!important}.mx-md-0{margin-right:0!important;margin-left:0!important}.mx-md-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-md-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-md-3{margin-right:1rem!important;margin-left:1rem!important}.mx-md-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-md-5{margin-right:3rem!important;margin-left:3rem!important}.mx-md-auto{margin-right:auto!important;margin-left:auto!important}.my-md-0{margin-top:0!important;margin-bottom:0!important}.my-md-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-md-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-md-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-md-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-md-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-md-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-md-0{margin-top:0!important}.mt-md-1{margin-top:.25rem!important}.mt-md-2{margin-top:.5rem!important}.mt-md-3{margin-top:1rem!important}.mt-md-4{margin-top:1.5rem!important}.mt-md-5{margin-top:3rem!important}.mt-md-auto{margin-top:auto!important}.me-md-0{margin-right:0!important}.me-md-1{margin-right:.25rem!important}.me-md-2{margin-right:.5rem!important}.me-md-3{margin-right:1rem!important}.me-md-4{margin-right:1.5rem!important}.me-md-5{margin-right:3rem!important}.me-md-auto{margin-right:auto!important}.mb-md-0{margin-bottom:0!important}.mb-md-1{margin-bottom:.25rem!important}.mb-md-2{margin-bottom:.5rem!important}.mb-md-3{margin-bottom:1rem!important}.mb-md-4{margin-bottom:1.5rem!important}.mb-md-5{margin-bottom:3rem!important}.mb-md-auto{margin-bottom:auto!important}.ms-md-0{margin-left:0!important}.ms-md-1{margin-left:.25rem!important}.ms-md-2{margin-left:.5rem!important}.ms-md-3{margin-left:1rem!important}.ms-md-4{margin-left:1.5rem!important}.ms-md-5{margin-left:3rem!important}.ms-md-auto{margin-left:auto!important}.p-md-0{padding:0!important}.p-md-1{padding:.25rem!important}.p-md-2{padding:.5rem!important}.p-md-3{padding:1rem!important}.p-md-4{padding:1.5rem!important}.p-md-5{padding:3rem!important}.px-md-0{padding-right:0!important;padding-left:0!important}.px-md-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-md-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-md-3{padding-right:1rem!important;padding-left:1rem!important}.px-md-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-md-5{padding-right:3rem!important;padding-left:3rem!important}.py-md-0{padding-top:0!important;padding-bottom:0!important}.py-md-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-md-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-md-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-md-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-md-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-md-0{padding-top:0!important}.pt-md-1{padding-top:.25rem!important}.pt-md-2{padding-top:.5rem!important}.pt-md-3{padding-top:1rem!important}.pt-md-4{padding-top:1.5rem!important}.pt-md-5{padding-top:3rem!important}.pe-md-0{padding-right:0!important}.pe-md-1{padding-right:.25rem!important}.pe-md-2{padding-right:.5rem!important}.pe-md-3{padding-right:1rem!important}.pe-md-4{padding-right:1.5rem!important}.pe-md-5{padding-right:3rem!important}.pb-md-0{padding-bottom:0!important}.pb-md-1{padding-bottom:.25rem!important}.pb-md-2{padding-bottom:.5rem!important}.pb-md-3{padding-bottom:1rem!important}.pb-md-4{padding-bottom:1.5rem!important}.pb-md-5{padding-bottom:3rem!important}.ps-md-0{padding-left:0!important}.ps-md-1{padding-left:.25rem!important}.ps-md-2{padding-left:.5rem!important}.ps-md-3{padding-left:1rem!important}.ps-md-4{padding-left:1.5rem!important}.ps-md-5{padding-left:3rem!important}.text-md-start{text-align:left!important}.text-md-end{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.float-lg-start{float:left!important}.float-lg-end{float:right!important}.float-lg-none{float:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-grid{display:grid!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}.d-lg-none{display:none!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-lg-0{gap:0!important}.gap-lg-1{gap:.25rem!important}.gap-lg-2{gap:.5rem!important}.gap-lg-3{gap:1rem!important}.gap-lg-4{gap:1.5rem!important}.gap-lg-5{gap:3rem!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.justify-content-lg-evenly{justify-content:space-evenly!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}.order-lg-first{order:-1!important}.order-lg-0{order:0!important}.order-lg-1{order:1!important}.order-lg-2{order:2!important}.order-lg-3{order:3!important}.order-lg-4{order:4!important}.order-lg-5{order:5!important}.order-lg-last{order:6!important}.m-lg-0{margin:0!important}.m-lg-1{margin:.25rem!important}.m-lg-2{margin:.5rem!important}.m-lg-3{margin:1rem!important}.m-lg-4{margin:1.5rem!important}.m-lg-5{margin:3rem!important}.m-lg-auto{margin:auto!important}.mx-lg-0{margin-right:0!important;margin-left:0!important}.mx-lg-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-lg-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-lg-3{margin-right:1rem!important;margin-left:1rem!important}.mx-lg-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-lg-5{margin-right:3rem!important;margin-left:3rem!important}.mx-lg-auto{margin-right:auto!important;margin-left:auto!important}.my-lg-0{margin-top:0!important;margin-bottom:0!important}.my-lg-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-lg-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-lg-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-lg-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-lg-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-lg-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-lg-0{margin-top:0!important}.mt-lg-1{margin-top:.25rem!important}.mt-lg-2{margin-top:.5rem!important}.mt-lg-3{margin-top:1rem!important}.mt-lg-4{margin-top:1.5rem!important}.mt-lg-5{margin-top:3rem!important}.mt-lg-auto{margin-top:auto!important}.me-lg-0{margin-right:0!important}.me-lg-1{margin-right:.25rem!important}.me-lg-2{margin-right:.5rem!important}.me-lg-3{margin-right:1rem!important}.me-lg-4{margin-right:1.5rem!important}.me-lg-5{margin-right:3rem!important}.me-lg-auto{margin-right:auto!important}.mb-lg-0{margin-bottom:0!important}.mb-lg-1{margin-bottom:.25rem!important}.mb-lg-2{margin-bottom:.5rem!important}.mb-lg-3{margin-bottom:1rem!important}.mb-lg-4{margin-bottom:1.5rem!important}.mb-lg-5{margin-bottom:3rem!important}.mb-lg-auto{margin-bottom:auto!important}.ms-lg-0{margin-left:0!important}.ms-lg-1{margin-left:.25rem!important}.ms-lg-2{margin-left:.5rem!important}.ms-lg-3{margin-left:1rem!important}.ms-lg-4{margin-left:1.5rem!important}.ms-lg-5{margin-left:3rem!important}.ms-lg-auto{margin-left:auto!important}.p-lg-0{padding:0!important}.p-lg-1{padding:.25rem!important}.p-lg-2{padding:.5rem!important}.p-lg-3{padding:1rem!important}.p-lg-4{padding:1.5rem!important}.p-lg-5{padding:3rem!important}.px-lg-0{padding-right:0!important;padding-left:0!important}.px-lg-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-lg-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-lg-3{padding-right:1rem!important;padding-left:1rem!important}.px-lg-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-lg-5{padding-right:3rem!important;padding-left:3rem!important}.py-lg-0{padding-top:0!important;padding-bottom:0!important}.py-lg-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-lg-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-lg-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-lg-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-lg-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-lg-0{padding-top:0!important}.pt-lg-1{padding-top:.25rem!important}.pt-lg-2{padding-top:.5rem!important}.pt-lg-3{padding-top:1rem!important}.pt-lg-4{padding-top:1.5rem!important}.pt-lg-5{padding-top:3rem!important}.pe-lg-0{padding-right:0!important}.pe-lg-1{padding-right:.25rem!important}.pe-lg-2{padding-right:.5rem!important}.pe-lg-3{padding-right:1rem!important}.pe-lg-4{padding-right:1.5rem!important}.pe-lg-5{padding-right:3rem!important}.pb-lg-0{padding-bottom:0!important}.pb-lg-1{padding-bottom:.25rem!important}.pb-lg-2{padding-bottom:.5rem!important}.pb-lg-3{padding-bottom:1rem!important}.pb-lg-4{padding-bottom:1.5rem!important}.pb-lg-5{padding-bottom:3rem!important}.ps-lg-0{padding-left:0!important}.ps-lg-1{padding-left:.25rem!important}.ps-lg-2{padding-left:.5rem!important}.ps-lg-3{padding-left:1rem!important}.ps-lg-4{padding-left:1.5rem!important}.ps-lg-5{padding-left:3rem!important}.text-lg-start{text-align:left!important}.text-lg-end{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.float-xl-start{float:left!important}.float-xl-end{float:right!important}.float-xl-none{float:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-grid{display:grid!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}.d-xl-none{display:none!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xl-0{gap:0!important}.gap-xl-1{gap:.25rem!important}.gap-xl-2{gap:.5rem!important}.gap-xl-3{gap:1rem!important}.gap-xl-4{gap:1.5rem!important}.gap-xl-5{gap:3rem!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.justify-content-xl-evenly{justify-content:space-evenly!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}.order-xl-first{order:-1!important}.order-xl-0{order:0!important}.order-xl-1{order:1!important}.order-xl-2{order:2!important}.order-xl-3{order:3!important}.order-xl-4{order:4!important}.order-xl-5{order:5!important}.order-xl-last{order:6!important}.m-xl-0{margin:0!important}.m-xl-1{margin:.25rem!important}.m-xl-2{margin:.5rem!important}.m-xl-3{margin:1rem!important}.m-xl-4{margin:1.5rem!important}.m-xl-5{margin:3rem!important}.m-xl-auto{margin:auto!important}.mx-xl-0{margin-right:0!important;margin-left:0!important}.mx-xl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xl-auto{margin-right:auto!important;margin-left:auto!important}.my-xl-0{margin-top:0!important;margin-bottom:0!important}.my-xl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xl-0{margin-top:0!important}.mt-xl-1{margin-top:.25rem!important}.mt-xl-2{margin-top:.5rem!important}.mt-xl-3{margin-top:1rem!important}.mt-xl-4{margin-top:1.5rem!important}.mt-xl-5{margin-top:3rem!important}.mt-xl-auto{margin-top:auto!important}.me-xl-0{margin-right:0!important}.me-xl-1{margin-right:.25rem!important}.me-xl-2{margin-right:.5rem!important}.me-xl-3{margin-right:1rem!important}.me-xl-4{margin-right:1.5rem!important}.me-xl-5{margin-right:3rem!important}.me-xl-auto{margin-right:auto!important}.mb-xl-0{margin-bottom:0!important}.mb-xl-1{margin-bottom:.25rem!important}.mb-xl-2{margin-bottom:.5rem!important}.mb-xl-3{margin-bottom:1rem!important}.mb-xl-4{margin-bottom:1.5rem!important}.mb-xl-5{margin-bottom:3rem!important}.mb-xl-auto{margin-bottom:auto!important}.ms-xl-0{margin-left:0!important}.ms-xl-1{margin-left:.25rem!important}.ms-xl-2{margin-left:.5rem!important}.ms-xl-3{margin-left:1rem!important}.ms-xl-4{margin-left:1.5rem!important}.ms-xl-5{margin-left:3rem!important}.ms-xl-auto{margin-left:auto!important}.p-xl-0{padding:0!important}.p-xl-1{padding:.25rem!important}.p-xl-2{padding:.5rem!important}.p-xl-3{padding:1rem!important}.p-xl-4{padding:1.5rem!important}.p-xl-5{padding:3rem!important}.px-xl-0{padding-right:0!important;padding-left:0!important}.px-xl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xl-0{padding-top:0!important;padding-bottom:0!important}.py-xl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xl-0{padding-top:0!important}.pt-xl-1{padding-top:.25rem!important}.pt-xl-2{padding-top:.5rem!important}.pt-xl-3{padding-top:1rem!important}.pt-xl-4{padding-top:1.5rem!important}.pt-xl-5{padding-top:3rem!important}.pe-xl-0{padding-right:0!important}.pe-xl-1{padding-right:.25rem!important}.pe-xl-2{padding-right:.5rem!important}.pe-xl-3{padding-right:1rem!important}.pe-xl-4{padding-right:1.5rem!important}.pe-xl-5{padding-right:3rem!important}.pb-xl-0{padding-bottom:0!important}.pb-xl-1{padding-bottom:.25rem!important}.pb-xl-2{padding-bottom:.5rem!important}.pb-xl-3{padding-bottom:1rem!important}.pb-xl-4{padding-bottom:1.5rem!important}.pb-xl-5{padding-bottom:3rem!important}.ps-xl-0{padding-left:0!important}.ps-xl-1{padding-left:.25rem!important}.ps-xl-2{padding-left:.5rem!important}.ps-xl-3{padding-left:1rem!important}.ps-xl-4{padding-left:1.5rem!important}.ps-xl-5{padding-left:3rem!important}.text-xl-start{text-align:left!important}.text-xl-end{text-align:right!important}.text-xl-center{text-align:center!important}}@media (min-width:1400px){.float-xxl-start{float:left!important}.float-xxl-end{float:right!important}.float-xxl-none{float:none!important}.d-xxl-inline{display:inline!important}.d-xxl-inline-block{display:inline-block!important}.d-xxl-block{display:block!important}.d-xxl-grid{display:grid!important}.d-xxl-table{display:table!important}.d-xxl-table-row{display:table-row!important}.d-xxl-table-cell{display:table-cell!important}.d-xxl-flex{display:flex!important}.d-xxl-inline-flex{display:inline-flex!important}.d-xxl-none{display:none!important}.flex-xxl-fill{flex:1 1 auto!important}.flex-xxl-row{flex-direction:row!important}.flex-xxl-column{flex-direction:column!important}.flex-xxl-row-reverse{flex-direction:row-reverse!important}.flex-xxl-column-reverse{flex-direction:column-reverse!important}.flex-xxl-grow-0{flex-grow:0!important}.flex-xxl-grow-1{flex-grow:1!important}.flex-xxl-shrink-0{flex-shrink:0!important}.flex-xxl-shrink-1{flex-shrink:1!important}.flex-xxl-wrap{flex-wrap:wrap!important}.flex-xxl-nowrap{flex-wrap:nowrap!important}.flex-xxl-wrap-reverse{flex-wrap:wrap-reverse!important}.gap-xxl-0{gap:0!important}.gap-xxl-1{gap:.25rem!important}.gap-xxl-2{gap:.5rem!important}.gap-xxl-3{gap:1rem!important}.gap-xxl-4{gap:1.5rem!important}.gap-xxl-5{gap:3rem!important}.justify-content-xxl-start{justify-content:flex-start!important}.justify-content-xxl-end{justify-content:flex-end!important}.justify-content-xxl-center{justify-content:center!important}.justify-content-xxl-between{justify-content:space-between!important}.justify-content-xxl-around{justify-content:space-around!important}.justify-content-xxl-evenly{justify-content:space-evenly!important}.align-items-xxl-start{align-items:flex-start!important}.align-items-xxl-end{align-items:flex-end!important}.align-items-xxl-center{align-items:center!important}.align-items-xxl-baseline{align-items:baseline!important}.align-items-xxl-stretch{align-items:stretch!important}.align-content-xxl-start{align-content:flex-start!important}.align-content-xxl-end{align-content:flex-end!important}.align-content-xxl-center{align-content:center!important}.align-content-xxl-between{align-content:space-between!important}.align-content-xxl-around{align-content:space-around!important}.align-content-xxl-stretch{align-content:stretch!important}.align-self-xxl-auto{align-self:auto!important}.align-self-xxl-start{align-self:flex-start!important}.align-self-xxl-end{align-self:flex-end!important}.align-self-xxl-center{align-self:center!important}.align-self-xxl-baseline{align-self:baseline!important}.align-self-xxl-stretch{align-self:stretch!important}.order-xxl-first{order:-1!important}.order-xxl-0{order:0!important}.order-xxl-1{order:1!important}.order-xxl-2{order:2!important}.order-xxl-3{order:3!important}.order-xxl-4{order:4!important}.order-xxl-5{order:5!important}.order-xxl-last{order:6!important}.m-xxl-0{margin:0!important}.m-xxl-1{margin:.25rem!important}.m-xxl-2{margin:.5rem!important}.m-xxl-3{margin:1rem!important}.m-xxl-4{margin:1.5rem!important}.m-xxl-5{margin:3rem!important}.m-xxl-auto{margin:auto!important}.mx-xxl-0{margin-right:0!important;margin-left:0!important}.mx-xxl-1{margin-right:.25rem!important;margin-left:.25rem!important}.mx-xxl-2{margin-right:.5rem!important;margin-left:.5rem!important}.mx-xxl-3{margin-right:1rem!important;margin-left:1rem!important}.mx-xxl-4{margin-right:1.5rem!important;margin-left:1.5rem!important}.mx-xxl-5{margin-right:3rem!important;margin-left:3rem!important}.mx-xxl-auto{margin-right:auto!important;margin-left:auto!important}.my-xxl-0{margin-top:0!important;margin-bottom:0!important}.my-xxl-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.my-xxl-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.my-xxl-3{margin-top:1rem!important;margin-bottom:1rem!important}.my-xxl-4{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.my-xxl-5{margin-top:3rem!important;margin-bottom:3rem!important}.my-xxl-auto{margin-top:auto!important;margin-bottom:auto!important}.mt-xxl-0{margin-top:0!important}.mt-xxl-1{margin-top:.25rem!important}.mt-xxl-2{margin-top:.5rem!important}.mt-xxl-3{margin-top:1rem!important}.mt-xxl-4{margin-top:1.5rem!important}.mt-xxl-5{margin-top:3rem!important}.mt-xxl-auto{margin-top:auto!important}.me-xxl-0{margin-right:0!important}.me-xxl-1{margin-right:.25rem!important}.me-xxl-2{margin-right:.5rem!important}.me-xxl-3{margin-right:1rem!important}.me-xxl-4{margin-right:1.5rem!important}.me-xxl-5{margin-right:3rem!important}.me-xxl-auto{margin-right:auto!important}.mb-xxl-0{margin-bottom:0!important}.mb-xxl-1{margin-bottom:.25rem!important}.mb-xxl-2{margin-bottom:.5rem!important}.mb-xxl-3{margin-bottom:1rem!important}.mb-xxl-4{margin-bottom:1.5rem!important}.mb-xxl-5{margin-bottom:3rem!important}.mb-xxl-auto{margin-bottom:auto!important}.ms-xxl-0{margin-left:0!important}.ms-xxl-1{margin-left:.25rem!important}.ms-xxl-2{margin-left:.5rem!important}.ms-xxl-3{margin-left:1rem!important}.ms-xxl-4{margin-left:1.5rem!important}.ms-xxl-5{margin-left:3rem!important}.ms-xxl-auto{margin-left:auto!important}.p-xxl-0{padding:0!important}.p-xxl-1{padding:.25rem!important}.p-xxl-2{padding:.5rem!important}.p-xxl-3{padding:1rem!important}.p-xxl-4{padding:1.5rem!important}.p-xxl-5{padding:3rem!important}.px-xxl-0{padding-right:0!important;padding-left:0!important}.px-xxl-1{padding-right:.25rem!important;padding-left:.25rem!important}.px-xxl-2{padding-right:.5rem!important;padding-left:.5rem!important}.px-xxl-3{padding-right:1rem!important;padding-left:1rem!important}.px-xxl-4{padding-right:1.5rem!important;padding-left:1.5rem!important}.px-xxl-5{padding-right:3rem!important;padding-left:3rem!important}.py-xxl-0{padding-top:0!important;padding-bottom:0!important}.py-xxl-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.py-xxl-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.py-xxl-3{padding-top:1rem!important;padding-bottom:1rem!important}.py-xxl-4{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.py-xxl-5{padding-top:3rem!important;padding-bottom:3rem!important}.pt-xxl-0{padding-top:0!important}.pt-xxl-1{padding-top:.25rem!important}.pt-xxl-2{padding-top:.5rem!important}.pt-xxl-3{padding-top:1rem!important}.pt-xxl-4{padding-top:1.5rem!important}.pt-xxl-5{padding-top:3rem!important}.pe-xxl-0{padding-right:0!important}.pe-xxl-1{padding-right:.25rem!important}.pe-xxl-2{padding-right:.5rem!important}.pe-xxl-3{padding-right:1rem!important}.pe-xxl-4{padding-right:1.5rem!important}.pe-xxl-5{padding-right:3rem!important}.pb-xxl-0{padding-bottom:0!important}.pb-xxl-1{padding-bottom:.25rem!important}.pb-xxl-2{padding-bottom:.5rem!important}.pb-xxl-3{padding-bottom:1rem!important}.pb-xxl-4{padding-bottom:1.5rem!important}.pb-xxl-5{padding-bottom:3rem!important}.ps-xxl-0{padding-left:0!important}.ps-xxl-1{padding-left:.25rem!important}.ps-xxl-2{padding-left:.5rem!important}.ps-xxl-3{padding-left:1rem!important}.ps-xxl-4{padding-left:1.5rem!important}.ps-xxl-5{padding-left:3rem!important}.text-xxl-start{text-align:left!important}.text-xxl-end{text-align:right!important}.text-xxl-center{text-align:center!important}}@media (min-width:1200px){.fs-1{font-size:2.5rem!important}.fs-2{font-size:2rem!important}.fs-3{font-size:1.75rem!important}.fs-4{font-size:1.5rem!important}}@media print{.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-grid{display:grid!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}.d-print-none{display:none!important}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file +/*# sourceMappingURL=bootstrap.min.css.map */ diff --git a/go/ternweb/directory.html b/go/ternweb/directory.html index 1c086c78..cdb96aa7 100644 --- a/go/ternweb/directory.html +++ b/go/ternweb/directory.html @@ -1,3 +1,9 @@ + + {{define "body"}} diff --git a/go/ternweb/error.html b/go/ternweb/error.html index 54eef858..4230d627 100644 --- a/go/ternweb/error.html +++ b/go/ternweb/error.html @@ -1,3 +1,9 @@ + + {{define "body"}}
{{.}}
{{end}} \ No newline at end of file diff --git a/go/ternweb/file.html b/go/ternweb/file.html index 36f25068..f3c05c5d 100644 --- a/go/ternweb/file.html +++ b/go/ternweb/file.html @@ -1,3 +1,9 @@ + + {{define "body"}}
diff --git a/go/ternweb/index.html b/go/ternweb/index.html index ddc697c5..62596ff0 100644 --- a/go/ternweb/index.html +++ b/go/ternweb/index.html @@ -1,3 +1,9 @@ + + {{define "body"}}

CDC

Loading...
diff --git a/go/ternweb/preact-10.18.1.module.js b/go/ternweb/preact-10.18.1.module.js index 704fca5f..51fa29ba 100644 --- a/go/ternweb/preact-10.18.1.module.js +++ b/go/ternweb/preact-10.18.1.module.js @@ -1,2 +1,6 @@ +// Copyright (c) 2015-present Jason Miller +// +// SPDX-License-Identifier: MIT + var n,l,u,t,i,o,r,f,e,c={},s=[],a=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,v=Array.isArray;function h(n,l){for(var u in l)n[u]=l[u];return n}function p(n){var l=n.parentNode;l&&l.removeChild(n)}function y(l,u,t){var i,o,r,f={};for(r in u)"key"==r?i=u[r]:"ref"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):t),"function"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return d(l,f,i,o,null)}function d(n,t,i,o,r){var f={type:n,props:t,key:i,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u:r};return null==r&&null!=l.vnode&&l.vnode(f),f}function _(){return{current:null}}function k(n){return n.children}function b(n,l){this.props=n,this.context=l}function g(n,l){if(null==l)return n.__?g(n.__,n.__.__k.indexOf(n)+1):null;for(var u;ll&&i.sort(f));x.__r=0}function P(n,l,u,t,i,o,r,f,e,a,h){var p,y,_,b,m,w,x,P,C,D=0,H=t&&t.__k||s,I=H.length,T=I,j=l.length;for(u.__k=[],p=0;p0?d(b.type,b.props,b.key,b.ref?b.ref:null,b.__v):b)?(b.__=u,b.__b=u.__b+1,-1===(P=A(b,H,x=p+D,T))?_=c:(_=H[P]||c,H[P]=void 0,T--),z(n,b,_,i,o,r,f,e,a,h),m=b.__e,(y=b.ref)&&_.ref!=y&&(_.ref&&N(_.ref,null,b),h.push(y,b.__c||m,b)),null!=m&&(null==w&&(w=m),(C=_===c||null===_.__v)?-1==P&&D--:P!==x&&(P===x+1?D++:P>x?T>j-x?D+=P-x:D--:D=P(null!=e?1:0))for(;r>=0||f=0){if((e=l[r])&&i==e.key&&o===e.type)return r;r--}if(f2&&(e.children=arguments.length>3?n.call(arguments,2):t),d(l.type,e,i||l.key,o||l.ref,null)}function G(n,l){var u={__c:l="__cC"+e++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,t;return this.getChildContext||(u=[],(t={})[l]=this,this.getChildContext=function(){return t},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(function(n){n.__e=!0,w(n)})},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=s.slice,l={__e:function(n,l,u,t){for(var i,o,r;l=l.__;)if((i=l.__c)&&!i.__)try{if((o=i.constructor)&&null!=o.getDerivedStateFromError&&(i.setState(o.getDerivedStateFromError(n)),r=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),r=i.__d),r)return i.__E=i}catch(l){n=l}throw n}},u=0,t=function(n){return null!=n&&void 0===n.constructor},b.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=h({},this.state),"function"==typeof n&&(n=n(h({},u),this.props)),n&&h(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),w(this))},b.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),w(this))},b.prototype.render=k,i=[],r="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,f=function(n,l){return n.__v.__b-l.__v.__b},x.__r=0,e=0;export{b as Component,k as Fragment,F as cloneElement,G as createContext,y as createElement,_ as createRef,y as h,E as hydrate,t as isValidElement,l as options,B as render,C as toChildArray}; //# sourceMappingURL=preact-10.18.1.module.js.map diff --git a/go/ternweb/preact-hooks-10.18.1.module.js b/go/ternweb/preact-hooks-10.18.1.module.js index 70be8cef..3e323354 100644 --- a/go/ternweb/preact-hooks-10.18.1.module.js +++ b/go/ternweb/preact-hooks-10.18.1.module.js @@ -1,2 +1,6 @@ +// Copyright (c) 2015-present Jason Miller +// +// SPDX-License-Identifier: MIT + import{options as n}from"/static/preact-10.18.1.module.js";var t,r,u,i,o=0,f=[],c=[],e=n.__b,a=n.__r,v=n.diffed,l=n.__c,m=n.unmount;function d(t,u){n.__h&&n.__h(r,t,o||u),o=0;var i=r.__H||(r.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({__V:c}),i.__[t]}function h(n){return o=1,s(B,n)}function s(n,u,i){var o=d(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):B(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}))}],o.__c=r,!r.u)){var f=function(n,t,r){if(!o.__c.__H)return!0;var u=o.__c.__H.__.filter(function(n){return n.__c});if(u.every(function(n){return!n.__N}))return!c||c.call(this,n,t,r);var i=!1;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0)}}),!(!i&&o.__c.props===n)&&(!c||c.call(this,n,t,r))};r.u=!0;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u}e&&e.call(this,n,t,r)},r.shouldComponentUpdate=f}return o.__N||o.__}function p(u,i){var o=d(t++,3);!n.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__H.__h.push(o))}function y(u,i){var o=d(t++,4);!n.__s&&z(o.__H,i)&&(o.__=u,o.i=i,r.__h.push(o))}function _(n){return o=5,F(function(){return{current:n}},[])}function A(n,t,r){o=6,y(function(){return"function"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(n))}function F(n,r){var u=d(t++,7);return z(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function T(n,t){return o=8,F(function(){return n},t)}function q(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function x(t,r){n.useDebugValue&&n.useDebugValue(r?r(t):t)}function P(n){var u=d(t++,10),i=h();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n,t){u.__&&u.__(n,t),i[1](n)}),[i[0],function(){i[1](void 0)}]}function V(){var n=d(t++,11);if(!n.__){for(var u=r.__v;null!==u&&!u.__m&&null!==u.__;)u=u.__;var i=u.__m||(u.__m=[0,0]);n.__="P"+i[0]+"-"+i[1]++}return n.__}function b(){for(var t;t=f.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(k),t.__H.__h.forEach(w),t.__H.__h=[]}catch(r){t.__H.__h=[],n.__e(r,t.__v)}}n.__b=function(n){r=null,e&&e(n)},n.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=c,n.__N=n.i=void 0})):(i.__h.forEach(k),i.__h.forEach(w),i.__h=[],t=0)),u=r},n.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==f.push(o)&&i===n.requestAnimationFrame||((i=n.requestAnimationFrame)||j)(b)),o.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==c&&(n.__=n.__V),n.i=void 0,n.__V=c})),u=r=null},n.__c=function(t,r){r.some(function(t){try{t.__h.forEach(k),t.__h=t.__h.filter(function(n){return!n.__||w(n)})}catch(u){r.some(function(n){n.__h&&(n.__h=[])}),r=[],n.__e(u,t.__v)}}),l&&l(t,r)},n.unmount=function(t){m&&m(t);var r,u=t.__c;u&&u.__H&&(u.__H.__.forEach(function(n){try{k(n)}catch(n){r=n}}),u.__H=void 0,r&&n.__e(r,u.__v))};var g="function"==typeof requestAnimationFrame;function j(n){var t,r=function(){clearTimeout(u),g&&cancelAnimationFrame(t),setTimeout(n)},u=setTimeout(r,100);g&&(t=requestAnimationFrame(r))}function k(n){var t=r,u=n.__c;"function"==typeof u&&(n.__c=void 0,u()),r=t}function w(n){var t=r;n.__c=n.__(),r=t}function z(n,t){return!n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function B(n,t){return"function"==typeof t?t(n):t}export{T as useCallback,q as useContext,x as useDebugValue,p as useEffect,P as useErrorBoundary,V as useId,A as useImperativeHandle,y as useLayoutEffect,F as useMemo,s as useReducer,_ as useRef,h as useState}; //# sourceMappingURL=hooks.module.js.map diff --git a/go/ternweb/scripts.js b/go/ternweb/scripts.js index 06fcf282..e116116e 100644 --- a/go/ternweb/scripts.js +++ b/go/ternweb/scripts.js @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + import * as p from '/static/preact-10.18.1.module.js'; import { useEffect, useState, useCallback } from '/static/preact-hooks-10.18.1.module.js'; diff --git a/go/ternweb/ternfs.png.license b/go/ternweb/ternfs.png.license new file mode 100644 index 00000000..2dbd9090 --- /dev/null +++ b/go/ternweb/ternfs.png.license @@ -0,0 +1,3 @@ +Copyright 2025 XTX Markets Technologies Limited + +SPDX-License-Identifier: GPL-2.0-or-later diff --git a/go/ternweb/ternweb.go b/go/ternweb/ternweb.go index 664e2f35..a416d828 100644 --- a/go/ternweb/ternweb.go +++ b/go/ternweb/ternweb.go @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + package main import ( @@ -711,7 +715,7 @@ func handleBlock(l *log.Logger, st *state, w http.ResponseWriter, r *http.Reques { var blockService msgs.BlockServiceDeprecatedInfo { - blockServicesResp, err := st.client.RegistryRequest(l,&msgs.AllBlockServicesDeprecatedReq{}) + blockServicesResp, err := st.client.RegistryRequest(l, &msgs.AllBlockServicesDeprecatedReq{}) if err != nil { return sendPage(errorPage(http.StatusInternalServerError, fmt.Sprintf("Failed getting block services '%v'", err))) } @@ -870,7 +874,7 @@ func handleApi(l *log.Logger, st *state, w http.ResponseWriter, r *http.Request) if err := json.NewDecoder(r.Body).Decode(&req); err != nil { return sendJsonErr(w, fmt.Errorf("could not decode request: %v", err), http.StatusBadRequest) } - + resp, err := st.client.RegistryRequest(l, req) if err != nil { return sendJsonErr(w, err, http.StatusInternalServerError) @@ -1115,7 +1119,7 @@ func main() { flag.Parse() noRunawayArgs() - + if *registry == "" { fmt.Fprintf(os.Stderr, "-registry needs to be provided\n") os.Exit(2) @@ -1159,7 +1163,7 @@ func main() { defer httpListener.Close() config := ®istryConfig{ - addrs: msgs.AddrsInfo{}, + addrs: msgs.AddrsInfo{}, registryAddress: *registry, } state, err := newState(l, config) diff --git a/go/ternweb/transient.html b/go/ternweb/transient.html index 48cc4589..77bf60cf 100644 --- a/go/ternweb/transient.html +++ b/go/ternweb/transient.html @@ -1,3 +1,9 @@ + + {{define "body"}}

Transient files

Loading...
diff --git a/integration.py b/integration.py index 0a744b92..c7f6b0b0 100755 --- a/integration.py +++ b/integration.py @@ -1,4 +1,9 @@ #!/usr/bin/env -S python3 -u + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + import argparse import socket import os diff --git a/kmod/.gitignore b/kmod/.gitignore index eac212d0..d73ae44a 100644 --- a/kmod/.gitignore +++ b/kmod/.gitignore @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + *.qcow2 compile_commands.json *.o diff --git a/kmod/BUILD.md b/kmod/BUILD.md index 10e0823b..19cf4fde 100644 --- a/kmod/BUILD.md +++ b/kmod/BUILD.md @@ -1,3 +1,9 @@ + + To get a `compile_commands.json`: * Call the kmod source dir (where this file is located) `$KMOD_DIR` diff --git a/kmod/Makefile b/kmod/Makefile index 362c5526..19056d88 100644 --- a/kmod/Makefile +++ b/kmod/Makefile @@ -1,3 +1,7 @@ +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + KDIR ?= /lib/modules/$(shell uname -r)/build LLVM ?= 0 diff --git a/kmod/bincode.c b/kmod/bincode.c index ee2574e9..55c28fda 100644 --- a/kmod/bincode.c +++ b/kmod/bincode.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "bincode.h" #include "bincodegen.c" diff --git a/kmod/bincode.h b/kmod/bincode.h index 0b3f10d3..4ef51374 100644 --- a/kmod/bincode.h +++ b/kmod/bincode.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_BINCODE_H #define _TERNFS_BINCODE_H diff --git a/kmod/bincode_tests.c b/kmod/bincode_tests.c index a9f165bd..d3a655f1 100644 --- a/kmod/bincode_tests.c +++ b/kmod/bincode_tests.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/kmod/bincodegen.c b/kmod/bincodegen.c index 73622f53..b495229e 100644 --- a/kmod/bincodegen.c +++ b/kmod/bincodegen.c @@ -1,3 +1,10 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +// Automatically generated with go run bincodegen. +// Run `go generate ./...` from the go/ directory to regenerate it. + const char* ternfs_err_str(int err) { switch (err) { case 10: return "INTERNAL_ERROR"; diff --git a/kmod/bincodegen.h b/kmod/bincodegen.h index e02000da..f83d424f 100644 --- a/kmod/bincodegen.h +++ b/kmod/bincodegen.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + // Automatically generated with go run bincodegen. // Run `go generate ./...` from the go/ directory to regenerate it. diff --git a/kmod/block.c b/kmod/block.c index 6bdeb41f..5462a662 100644 --- a/kmod/block.c +++ b/kmod/block.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/kmod/block.h b/kmod/block.h index 2263df52..c3c76f37 100644 --- a/kmod/block.h +++ b/kmod/block.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_BLOCK_H #define _TERNFS_BLOCK_H diff --git a/kmod/block_services.c b/kmod/block_services.c index 0efa08fb..c4b9e93d 100644 --- a/kmod/block_services.c +++ b/kmod/block_services.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/kmod/block_services.h b/kmod/block_services.h index 0bf9cc27..d2f471c3 100644 --- a/kmod/block_services.h +++ b/kmod/block_services.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + // This cache is never cleared -- but it is small. For 100k disks, which is // what we're targeting, it'd be ~5MB. #ifndef _TERNFS_BLOCK_SERVICE_H diff --git a/kmod/build.sh b/kmod/build.sh index 9fb12af8..0f80036a 100755 --- a/kmod/build.sh +++ b/kmod/build.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail set -x diff --git a/kmod/ci.sh b/kmod/ci.sh index a613f27e..d2a9f959 100755 --- a/kmod/ci.sh +++ b/kmod/ci.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail short="" diff --git a/kmod/ci_prepare.sh b/kmod/ci_prepare.sh index d2247215..f18497f4 100755 --- a/kmod/ci_prepare.sh +++ b/kmod/ci_prepare.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail base_img="" diff --git a/kmod/counter.h b/kmod/counter.h index 19320508..4f76f815 100644 --- a/kmod/counter.h +++ b/kmod/counter.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_COUNTER_H #define _TERNFS_COUNTER_H diff --git a/kmod/crc.c b/kmod/crc.c index 64ce8bb8..aa0c6cd8 100644 --- a/kmod/crc.c +++ b/kmod/crc.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "crc.h" #ifndef __CHECKER__ // sparse doesn't like this code at all. diff --git a/kmod/crc.h b/kmod/crc.h index 6e0cc3f8..7ec1c7f2 100644 --- a/kmod/crc.h +++ b/kmod/crc.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_CRC_H #define _TERNFS_CRC_H diff --git a/kmod/createimg.sh b/kmod/createimg.sh index a9c2392a..20af5103 100755 --- a/kmod/createimg.sh +++ b/kmod/createimg.sh @@ -1,4 +1,9 @@ - #!/usr/bin/env bash +#!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail base_img=$(realpath ${1}) diff --git a/kmod/debugfs.c b/kmod/debugfs.c index 922f9132..16e243c1 100644 --- a/kmod/debugfs.c +++ b/kmod/debugfs.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/kmod/debugfs.h b/kmod/debugfs.h index 632bec1f..ecb543e2 100644 --- a/kmod/debugfs.h +++ b/kmod/debugfs.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_DEBUGFS_H #define _TERNFS_DEBUGFS_H diff --git a/kmod/dentry.c b/kmod/dentry.c index a71561ff..67f40636 100644 --- a/kmod/dentry.c +++ b/kmod/dentry.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "dentry.h" #include "inode_compat.h" diff --git a/kmod/dentry.h b/kmod/dentry.h index 096abfc0..c2b29908 100644 --- a/kmod/dentry.h +++ b/kmod/dentry.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_DENTRY_H #define _TERNFS_DENTRY_H diff --git a/kmod/dir.c b/kmod/dir.c index 354b50c3..1b753d32 100644 --- a/kmod/dir.c +++ b/kmod/dir.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "dir.h" #include diff --git a/kmod/dir.h b/kmod/dir.h index b84ceb3c..e8069975 100644 --- a/kmod/dir.h +++ b/kmod/dir.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_DIR_H #define _TERNFS_DIR_H diff --git a/kmod/err.c b/kmod/err.c index 72831ca6..ab8dd4a1 100644 --- a/kmod/err.c +++ b/kmod/err.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "err.h" #include "log.h" #include "bincode.h" diff --git a/kmod/err.h b/kmod/err.h index ff596168..5ecca7a5 100644 --- a/kmod/err.h +++ b/kmod/err.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_ERR_H #define _TERNFS_ERR_H diff --git a/kmod/export.c b/kmod/export.c index d7a3583f..8e42267c 100644 --- a/kmod/export.c +++ b/kmod/export.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "export.h" #include "inode.h" #include "metadata.h" diff --git a/kmod/export.h b/kmod/export.h index c82aa0aa..c2e6834a 100644 --- a/kmod/export.h +++ b/kmod/export.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_EXPORT_H #define _TERNFS_EXPORT_H diff --git a/kmod/fetchlinux.sh b/kmod/fetchlinux.sh index 202a8738..1c7cb23c 100755 --- a/kmod/fetchlinux.sh +++ b/kmod/fetchlinux.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail version=linux-5.4.237 diff --git a/kmod/file.c b/kmod/file.c index 2c0a566f..5b3e2a9e 100644 --- a/kmod/file.c +++ b/kmod/file.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "file.h" #include diff --git a/kmod/file.h b/kmod/file.h index a814aef2..49fbae82 100644 --- a/kmod/file.h +++ b/kmod/file.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_FILE_H #define _TERNFS_FILE_H diff --git a/kmod/gen_compile_commands.sh b/kmod/gen_compile_commands.sh index 56e8dc83..c594163e 100755 --- a/kmod/gen_compile_commands.sh +++ b/kmod/gen_compile_commands.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) diff --git a/kmod/inode.c b/kmod/inode.c index 85601f9b..04d2d6bd 100644 --- a/kmod/inode.c +++ b/kmod/inode.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "inode.h" #include diff --git a/kmod/inode.h b/kmod/inode.h index 1d8ec275..e4932235 100644 --- a/kmod/inode.h +++ b/kmod/inode.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_INODE_H #define _TERNFS_INODE_H diff --git a/kmod/inode_compat.h b/kmod/inode_compat.h index 87990c69..c1a7aef3 100644 --- a/kmod/inode_compat.h +++ b/kmod/inode_compat.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_INODE_COMPAT_H #define _TERNFS_INODE_COMPAT_H #include diff --git a/kmod/intrshims.h b/kmod/intrshims.h index cbe4e620..e56de6fc 100644 --- a/kmod/intrshims.h +++ b/kmod/intrshims.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_INTRSHIMS_H #define _TERNFS_INTRSHIMS_H diff --git a/kmod/kmod.c b/kmod/kmod.c index 1581de98..a2112d13 100644 --- a/kmod/kmod.c +++ b/kmod/kmod.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/kmod/latch.h b/kmod/latch.h index b5442fa0..4b2549d8 100644 --- a/kmod/latch.h +++ b/kmod/latch.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_LATCH_H #define _TERNFS_LATCH_H diff --git a/kmod/log.h b/kmod/log.h index 7a3a583a..4e34258f 100644 --- a/kmod/log.h +++ b/kmod/log.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_LOG_H #define _TERNFS_LOG_H diff --git a/kmod/metadata.c b/kmod/metadata.c index e3417715..e93eebe5 100644 --- a/kmod/metadata.c +++ b/kmod/metadata.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "metadata.h" #include diff --git a/kmod/metadata.h b/kmod/metadata.h index 041dc362..6438392e 100644 --- a/kmod/metadata.h +++ b/kmod/metadata.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_SHARD_H #define _TERNFS_SHARD_H diff --git a/kmod/net.c b/kmod/net.c index 54a1c202..fd58ac0a 100644 --- a/kmod/net.c +++ b/kmod/net.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "net.h" #include diff --git a/kmod/net.h b/kmod/net.h index 12954683..ad4db2af 100644 --- a/kmod/net.h +++ b/kmod/net.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_NET_H #define _TERNFS_NET_H diff --git a/kmod/net_compat.h b/kmod/net_compat.h index 797b1dc2..318e1803 100644 --- a/kmod/net_compat.h +++ b/kmod/net_compat.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_NET_COMPAT_H #define _TERNFS_NET_COMPAT_H #include diff --git a/kmod/policy.c b/kmod/policy.c index 4541d730..1d3198d5 100644 --- a/kmod/policy.c +++ b/kmod/policy.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "policy.h" #include diff --git a/kmod/policy.h b/kmod/policy.h index b879e8a0..469fc762 100644 --- a/kmod/policy.h +++ b/kmod/policy.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + // We index policies by (inode, tag), so that the automatically get updated // when the getattr for the inode runs. They never get freed, there should // be very few of them. diff --git a/kmod/registry.c b/kmod/registry.c index 28216858..f8f2ed1e 100644 --- a/kmod/registry.c +++ b/kmod/registry.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/kmod/registry.h b/kmod/registry.h index b1b4aed7..13478efb 100644 --- a/kmod/registry.h +++ b/kmod/registry.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_REGISTRY_H #define _TERNFS_REGISTRY_H diff --git a/kmod/restartsession.sh b/kmod/restartsession.sh index c42dad05..6cb29d7b 100755 --- a/kmod/restartsession.sh +++ b/kmod/restartsession.sh @@ -1,5 +1,9 @@ #!/usr/bin/env bash +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail run=false diff --git a/kmod/rs.c b/kmod/rs.c index 3db6b0be..873c85a7 100644 --- a/kmod/rs.c +++ b/kmod/rs.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "rs.h" #ifndef __CHECKER__ // sparse doesn't like this code at all. diff --git a/kmod/rs.h b/kmod/rs.h index 92ca2e13..4f174f59 100644 --- a/kmod/rs.h +++ b/kmod/rs.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_RS_H #define _TERNFS_RS_H diff --git a/kmod/span.c b/kmod/span.c index 80aa219c..0bedd9f6 100644 --- a/kmod/span.c +++ b/kmod/span.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include #include diff --git a/kmod/span.h b/kmod/span.h index 02d74b1f..c896c862 100644 --- a/kmod/span.h +++ b/kmod/span.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_SPAN_H #define _TERNFS_SPAN_H diff --git a/kmod/startvm.sh b/kmod/startvm.sh index a254a9df..77e0e500 100755 --- a/kmod/startvm.sh +++ b/kmod/startvm.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) diff --git a/kmod/super.c b/kmod/super.c index 1e800cd9..13aeb603 100644 --- a/kmod/super.c +++ b/kmod/super.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "super.h" #include diff --git a/kmod/super.h b/kmod/super.h index 2ba2bd60..8bca39db 100644 --- a/kmod/super.h +++ b/kmod/super.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_SUPER_H #define _TERNFS_SUPER_H diff --git a/kmod/sync.sh b/kmod/sync.sh index be7d3c93..153007a9 100755 --- a/kmod/sync.sh +++ b/kmod/sync.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + set -eu -o pipefail SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) diff --git a/kmod/sysctl.c b/kmod/sysctl.c index dac92e01..a8af816a 100644 --- a/kmod/sysctl.c +++ b/kmod/sysctl.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include #include diff --git a/kmod/sysctl.h b/kmod/sysctl.h index 699ea555..cb9d3637 100644 --- a/kmod/sysctl.h +++ b/kmod/sysctl.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_SYSCTL_H #define _TERNFS_SYSCTL_H diff --git a/kmod/sysfs.c b/kmod/sysfs.c index 225d1b67..81a4ddf6 100644 --- a/kmod/sysfs.c +++ b/kmod/sysfs.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #include "sysfs.h" #include diff --git a/kmod/sysfs.h b/kmod/sysfs.h index af51334f..bc8957ea 100644 --- a/kmod/sysfs.h +++ b/kmod/sysfs.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_SYSFS_H #define _TERNFS_SYSFS_H diff --git a/kmod/trace.c b/kmod/trace.c index 61159f15..51768eb0 100644 --- a/kmod/trace.c +++ b/kmod/trace.c @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #define CREATE_TRACE_POINTS #include "trace.h" diff --git a/kmod/trace.h b/kmod/trace.h index a4c47612..8e301e98 100644 --- a/kmod/trace.h +++ b/kmod/trace.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #undef TRACE_SYSTEM #define TRACE_SYSTEM eggsfs diff --git a/kmod/vm_deploy.py b/kmod/vm_deploy.py index f333721a..5db5e340 100755 --- a/kmod/vm_deploy.py +++ b/kmod/vm_deploy.py @@ -1,4 +1,9 @@ #!/usr/bin/env python3 + +# Copyright 2025 XTX Markets Technologies Limited +# +# SPDX-License-Identifier: GPL-2.0-or-later + """ Utility for importing binaries into vm for tests """ @@ -44,4 +49,4 @@ if __name__ == "__main__": "--build-type", choices=["alpine", "alpinedebug"], default="alpine" ) args = parser.parse_args() - build_and_upload(args.build_type) \ No newline at end of file + build_and_upload(args.build_type) diff --git a/kmod/wq.h b/kmod/wq.h index b7fe37b1..fd767998 100644 --- a/kmod/wq.h +++ b/kmod/wq.h @@ -1,3 +1,7 @@ +// Copyright 2025 XTX Markets Technologies Limited +// +// SPDX-License-Identifier: GPL-2.0-or-later + #ifndef _TERNFS_WQ_H #define _TERNFS_WQ_H