From 4ce19d404f2ead569b60c3e5c74eaccb09199488 Mon Sep 17 00:00:00 2001 From: Yo Eight Date: Wed, 14 May 2025 16:28:24 -0400 Subject: [PATCH 01/18] feat: supports new caught up and fell behind events. (#325) --- .../dbclient/ReadResponseObserver.java | 21 +++++++--- .../kurrent/dbclient/ReadStreamConsumer.java | 6 ++- .../io/kurrent/dbclient/StreamConsumer.java | 6 ++- .../dbclient/SubscriptionListener.java | 6 ++- .../dbclient/SubscriptionStreamConsumer.java | 9 ++-- src/main/proto/streams.proto | 41 ++++++++++++++++++- .../dbclient/streams/SubscriptionTests.java | 3 +- 7 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/main/java/io/kurrent/dbclient/ReadResponseObserver.java b/src/main/java/io/kurrent/dbclient/ReadResponseObserver.java index da6408c8..029d30a2 100644 --- a/src/main/java/io/kurrent/dbclient/ReadResponseObserver.java +++ b/src/main/java/io/kurrent/dbclient/ReadResponseObserver.java @@ -12,6 +12,7 @@ import org.slf4j.LoggerFactory; import java.nio.charset.Charset; +import java.time.Instant; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; @@ -118,11 +119,21 @@ else if (value.hasLastStreamPosition()) else if (value.hasLastAllStreamPosition()) { Shared.AllStreamPosition position = value.getLastAllStreamPosition(); consumer.onLastAllStreamPosition(position.getCommitPosition(), position.getPreparePosition()); - } else if (value.hasCaughtUp()) - consumer.onCaughtUp(); - else if (value.hasFellBehind()) - consumer.onFellBehind(); - else { + } else if (value.hasCaughtUp()) { + StreamsOuterClass.ReadResp.CaughtUp caughtUp = value.getCaughtUp(); + Instant timestamp = Instant.ofEpochSecond(caughtUp.getTimestamp().getSeconds(), caughtUp.getTimestamp().getNanos()); + Long streamRevision = caughtUp.hasStreamRevision() ? caughtUp.getStreamRevision() : null; + Position position = caughtUp.hasPosition() ? new Position(caughtUp.getPosition().getCommitPosition(), caughtUp.getPosition().getPreparePosition()) : null; + + consumer.onCaughtUp(timestamp, streamRevision, position); + } else if (value.hasFellBehind()) { + StreamsOuterClass.ReadResp.FellBehind fellBehind = value.getFellBehind(); + Instant timestamp = Instant.ofEpochSecond(fellBehind.getTimestamp().getSeconds(), fellBehind.getTimestamp().getNanos()); + Long streamRevision = fellBehind.hasStreamRevision() ? fellBehind.getStreamRevision() : null; + Position position = fellBehind.hasPosition() ? new Position(fellBehind.getPosition().getCommitPosition(), fellBehind.getPosition().getPreparePosition()) : null; + + consumer.onFellBehind(timestamp, streamRevision, position); + } else { logger.warn("received unknown message variant"); } diff --git a/src/main/java/io/kurrent/dbclient/ReadStreamConsumer.java b/src/main/java/io/kurrent/dbclient/ReadStreamConsumer.java index 492f0088..a4c30aad 100644 --- a/src/main/java/io/kurrent/dbclient/ReadStreamConsumer.java +++ b/src/main/java/io/kurrent/dbclient/ReadStreamConsumer.java @@ -2,6 +2,8 @@ import org.reactivestreams.Subscriber; +import java.time.Instant; + class ReadStreamConsumer implements StreamConsumer { private final Subscriber subscriber; @@ -41,10 +43,10 @@ public void onLastAllStreamPosition(long commit, long prepare) { } @Override - public void onCaughtUp() {} + public void onCaughtUp(Instant timestamp, Long streamRevision, Position position) {} @Override - public void onFellBehind() {} + public void onFellBehind(Instant timestamp, Long streamRevision, Position position) {} @Override public void onCancelled(Throwable exception) { diff --git a/src/main/java/io/kurrent/dbclient/StreamConsumer.java b/src/main/java/io/kurrent/dbclient/StreamConsumer.java index 36613e22..8bd4c8e1 100644 --- a/src/main/java/io/kurrent/dbclient/StreamConsumer.java +++ b/src/main/java/io/kurrent/dbclient/StreamConsumer.java @@ -1,5 +1,7 @@ package io.kurrent.dbclient; +import java.time.Instant; + public interface StreamConsumer { default void onSubscribe(org.reactivestreams.Subscription subscription) {} void onEvent(ResolvedEvent event); @@ -9,8 +11,8 @@ default void onSubscribe(org.reactivestreams.Subscription subscription) {} void onFirstStreamPosition(long position); void onLastStreamPosition(long position); void onLastAllStreamPosition(long commit, long prepare); - void onCaughtUp(); - void onFellBehind(); + void onCaughtUp(Instant timestamp, Long streamRevision, Position position); + void onFellBehind(Instant timestamp, Long streamRevision, Position position); void onCancelled(Throwable exception); void onComplete(); } diff --git a/src/main/java/io/kurrent/dbclient/SubscriptionListener.java b/src/main/java/io/kurrent/dbclient/SubscriptionListener.java index afd62fa1..5fc43989 100644 --- a/src/main/java/io/kurrent/dbclient/SubscriptionListener.java +++ b/src/main/java/io/kurrent/dbclient/SubscriptionListener.java @@ -1,5 +1,7 @@ package io.kurrent.dbclient; +import java.time.Instant; + /** * Listener used to handle catch-up subscription notifications raised throughout its lifecycle. */ @@ -28,12 +30,12 @@ public void onConfirmation(Subscription subscription) {} * Called when the subscription has reached the head of the stream. * @param subscription handle to the subscription. */ - public void onCaughtUp(Subscription subscription) {} + public void onCaughtUp(Subscription subscription, Instant timestamp, Long streamRevision, Position position) {} /** * Called when the subscription has fallen behind, meaning it's no longer keeping up with the * stream's pace. * @param subscription handle to the subscription. */ - public void onFellBehind(Subscription subscription) {} + public void onFellBehind(Subscription subscription, Instant timestamp, Long streamRevision, Position position) {} } diff --git a/src/main/java/io/kurrent/dbclient/SubscriptionStreamConsumer.java b/src/main/java/io/kurrent/dbclient/SubscriptionStreamConsumer.java index 4770cfef..80f70a12 100644 --- a/src/main/java/io/kurrent/dbclient/SubscriptionStreamConsumer.java +++ b/src/main/java/io/kurrent/dbclient/SubscriptionStreamConsumer.java @@ -1,6 +1,7 @@ package io.kurrent.dbclient; +import java.time.Instant; import java.util.concurrent.CompletableFuture; class SubscriptionStreamConsumer implements StreamConsumer { @@ -56,13 +57,13 @@ public void onLastStreamPosition(long position) {} public void onLastAllStreamPosition(long commit, long prepare) {} @Override - public void onCaughtUp() { - this.listener.onCaughtUp(this.subscription); + public void onCaughtUp(Instant timestamp, Long streamRevision, Position position) { + this.listener.onCaughtUp(this.subscription, timestamp, streamRevision, position); } @Override - public void onFellBehind() { - this.listener.onFellBehind(this.subscription); + public void onFellBehind(Instant timestamp, Long streamRevision, Position position) { + this.listener.onFellBehind(this.subscription, timestamp, streamRevision, position); } @Override diff --git a/src/main/proto/streams.proto b/src/main/proto/streams.proto index 0eb05295..4ff613a7 100644 --- a/src/main/proto/streams.proto +++ b/src/main/proto/streams.proto @@ -103,9 +103,37 @@ message ReadResp { FellBehind fell_behind = 9; } - message CaughtUp {} + // The $all or stream subscription has caught up and become live. + message CaughtUp { + // Current time in the server when the subscription caught up + google.protobuf.Timestamp timestamp = 1; + + // Checkpoint for resuming a stream subscription. + // For stream subscriptions it is populated unless the stream is empty. + // For $all subscriptions it is not populated. + optional int64 stream_revision = 2; + + // Checkpoint for resuming a $all subscription. + // For stream subscriptions it is not populated. + // For $all subscriptions it is populated unless the database is empty. + optional Position position = 3; + } + + // The $all or stream subscription has fallen back into catchup mode and is no longer live. + message FellBehind { + // Current time in the server when the subscription fell behind + google.protobuf.Timestamp timestamp = 1; + + // Checkpoint for resuming a stream subscription. + // For stream subscriptions it is populated unless the stream is empty. + // For $all subscriptions it is not populated. + optional int64 stream_revision = 2; - message FellBehind {} + // Checkpoint for resuming a $all subscription. + // For stream subscriptions it is not populated. + // For $all subscriptions it is populated unless the database is empty. + optional Position position = 3; + } message ReadEvent { RecordedEvent event = 1; @@ -132,7 +160,16 @@ message ReadResp { message Checkpoint { uint64 commit_position = 1; uint64 prepare_position = 2; + + // Current time in the server when the checkpoint was reached + google.protobuf.Timestamp timestamp = 3; } + + message Position { + uint64 commit_position = 1; + uint64 prepare_position = 2; + } + message StreamNotFound { event_store.client.StreamIdentifier stream_identifier = 1; } diff --git a/src/test/java/io/kurrent/dbclient/streams/SubscriptionTests.java b/src/test/java/io/kurrent/dbclient/streams/SubscriptionTests.java index c05e6f68..9798ee42 100644 --- a/src/test/java/io/kurrent/dbclient/streams/SubscriptionTests.java +++ b/src/test/java/io/kurrent/dbclient/streams/SubscriptionTests.java @@ -7,6 +7,7 @@ import org.junit.jupiter.api.Timeout; import java.io.IOException; +import java.time.Instant; import java.util.ArrayList; import java.util.Optional; import java.util.concurrent.CountDownLatch; @@ -176,7 +177,7 @@ default void testCaughtUpMessageIsReceived() throws Throwable { Subscription subscription = client.subscribeToStream(streamName, new SubscriptionListener() { @Override - public void onCaughtUp(Subscription subscription) { + public void onCaughtUp(Subscription subscription, Instant timestamp, Long streamRevision, Position position) { caughtUp.countDown(); } }, SubscribeToStreamOptions.get().fromStart()).get(); From 0d132b2f0a0c6f6b62af11a8837ecef321db82a5 Mon Sep 17 00:00:00 2001 From: William Chong Date: Mon, 2 Jun 2025 09:28:55 +0400 Subject: [PATCH 02/18] Change License --- LICENSE | 201 +++++++++++++++++++++++++++++++++++++++++++++++++++++ LICENSE.md | 57 --------------- 2 files changed, 201 insertions(+), 57 deletions(-) create mode 100644 LICENSE delete mode 100644 LICENSE.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..0fdf6854 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + 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 2011-2025 Kurrent, Inc + + 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/LICENSE.md b/LICENSE.md deleted file mode 100644 index aac3fc04..00000000 --- a/LICENSE.md +++ /dev/null @@ -1,57 +0,0 @@ -# Kurrent License v1 - -Copyright (c) 2011-2025, Kurrent, Inc. All rights reserved. - -### Acceptance - -By using the software, you agree to all of the terms and conditions below. - -### Copyright License - -The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below. - -### Limitations - -You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software. - -Unless authorized in writing by the licensor, you may not move, change, disable, interfere with, or circumvent the license mechanisms in the software, and you may not remove or obscure any functionality in the software that is protected by the license mechanisms. - -You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law. - -### Patents - -The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company. - -### Notices - -You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms. - -If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software. - -### No Other Rights - -These terms do not imply any licenses other than those expressly granted in these terms. - -### Termination - -If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently. - -### No Liability - -***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.*** - -### Definitions - -The **licensor** is the entity offering these terms, and the **software** is the software the licensor makes available under these terms, including any portion of it. - -**licensing mechanisms** refers to functionality that restricts use of the software based on whether you possess a valid license key, including functionality to validate license keys and audit usage of the software to ensure license compliance. - -**you** refers to the individual or entity agreeing to these terms. - -**your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. - -**your licenses** are all the licenses granted to you for the software under these terms. - -**use** means anything you do with the software requiring one of your licenses. - -**trademark** means trademarks, service marks, and similar rights. \ No newline at end of file From 575cf9617cfdffb615beeaff828cd696fb1f77b3 Mon Sep 17 00:00:00 2001 From: William Chong Date: Thu, 5 Jun 2025 11:55:35 +0400 Subject: [PATCH 03/18] Deprecate CHANGELOG.md --- CHANGELOG.md | 152 +-------------------------------------------------- 1 file changed, 1 insertion(+), 151 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c5fb601..4d3794a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,151 +1 @@ -# Changelog -All notable changes to this project will be documented in this file. - -## [Unreleased] - -### Changed -- rebranding [EventStoreDB-Client-Java#294](https://github.com/kurrent-io/EventStoreDB-Client-Java/pull/294) - -## [5.4.5] - 2025-03-24 - -### Fixed -- Fix subscription error handling during server shutdown [EventStoreDB-Client-Java#311](https://github.com/EventStore/EventStoreDB-Client-Java/pull/311) - -## [5.4.4] - 2025-03-05 -### Changed -- Upgrade dependencies to latest [EventStoreDB-Client-Java#304](https://github.com/EventStore/EventStoreDB-Client-Java/pull/304) - -### Fixed -- Support back-pressure on reads and subscriptions. [EventStoreDB-Client-Java#292](https://github.com/EventStore/EventStoreDB-Client-Java/pull/295) -- Unwrap CompletionException in GrpcClient. [EventStoreDB-Client-Java#298](https://github.com/EventStore/EventStoreDB-Client-Java/pull/298) - -## [5.4.3] - 2024-11-07 -### Fixed -- Disable trace context extraction for deleted events. [EventStoreDB-Client-Java#292](https://github.com/EventStore/EventStoreDB-Client-Java/pull/292) - -## [5.4.2] - 2024-10-16 -### Added -- Support custom headers. [EventStoreDB-Client-Java#289](https://github.com/EventStore/EventStoreDB-Client-Java/pull/289) - -### Changed -- Extract tracing metadata from Event. [EventStoreDB-Client-Java#284](https://github.com/EventStore/EventStoreDB-Client-Java/pull/284) - -## [5.4.1] - 2024-07-16 -### Changed -- Add user certificates and otel samples. [EventStoreDB-Client-Java#274](https://github.com/EventStore/EventStoreDB-Client-Java/pull/274) -- Support different runtime environments out-of-the-box. [EventStoreDB-Client-Java#279](https://github.com/EventStore/EventStoreDB-Client-Java/pull/279) -- Remove expectation oriented tests. [EventStoreDB-Client-Java#279](https://github.com/EventStore/EventStoreDB-Client-Java/pull/279) -- Fixed bug in the ClientTelemetry whereby injection logic forces all events to have JSON content type. [EventStoreDB-Client-Java#281](https://github.com/EventStore/EventStoreDB-Client-Java/pull/281) - -### Fixed -- Use connection string in user certificate sample. [EventStoreDB-Client-Java#276](https://github.com/EventStore/EventStoreDB-Client-Java/pull/276) -- Fix connection service skipping discovery interval sleeps. [EventStoreDB-Client-Java#278](https://github.com/EventStore/EventStoreDB-Client-Java/pull/278) - -## [5.4.0] - 2024-05-23 -### Added -- new connection settings to provide an x.509 certificate for user authentication. [EventStoreDB-Client-Java#266](https://github.com/EventStore/EventStoreDB-Client-Java/pull/266) - -### Changed -- Updated CI workflows and tests to pull eventstore docker images from cloud smith registry. [EventStoreDB-Client-Java#263](https://github.com/EventStore/EventStoreDB-Client-Java/pull/263) -- Added tracing instrumentation of Append and Subscribe (Catchup and Persistent) operations using the Open Telemetry APIs. [EventStoreDB-Client-Java#270](https://github.com/EventStore/EventStoreDB-Client-Java/pull/270) -- Updated everywhere to pull es-gencert-cli from Cloudsmith [EventStoreDB-Client-Java#271](https://github.com/EventStore/EventStoreDB-Client-Java/pull/271) - -## [5.3.2] - 2024-03-05 -### Changed -- Updated protobuf & protoc to 3.25.3 [EventStoreDB-Client-Java#268](https://github.com/EventStore/EventStoreDB-Client-Java/pull/268) - -### Fixed -- https://github.com/EventStore/EventStoreDB-Client-Java/issues/267 [EventStoreDB-Client-Java#268](https://github.com/EventStore/EventStoreDB-Client-Java/pull/268) - -## [5.3.1] - 2024-02-29 -### Changed -- Updated gRPC client and Protoc to latest, which come with arm64 binaries, enabling compile on arm64 [EventStoreDB-Client-Java#265](https://github.com/EventStore/EventStoreDB-Client-Java/pull/265) - -### Fixed -- parsing of server semver for CI, where the server version may have tagging [EventStoreDB-Client-Java#264](https://github.com/EventStore/EventStoreDB-Client-Java/pull/264) - -## [5.3.0] - 2024-01-31 -### Added -- Expose building a JSON payload event with raw bytes [EventStoreDB-Client-Java#258](https://github.com/EventStore/EventStoreDB-Client-Java/pull/258) - -### Fixed -- Fix cluster discovery process. [EventStoreDB-Client-Java#261](https://github.com/EventStore/EventStoreDB-Client-Java/pull/261) - -## [5.2.0] - 2023-11-10 -### Added -- Support new subscription messages. [EventStoreDB-Client-Java#254](https://github.com/EventStore/EventStoreDB-Client-Java/pull/254) - -## [5.1.1] - 2023-11-03 -### Fixed -- Fix IllegalStateException when stopping a subscription. [EventStoreDB-Client-Java#250](https://github.com/EventStore/EventStoreDB-Client-Java/pull/250) - -## [5.1.0] - 2023-10-31 -### Added -- Support certificate file input in connection string and builder. [EventStoreDB-Client-Java#247](https://github.com/EventStore/EventStoreDB-Client-Java/pull/247) - -### Changed -- Improve error reporting in SubscriptionListener. [EventStoreDB-Client-Java#245](https://github.com/EventStore/EventStoreDB-Client-Java/pull/245) -- Update dependencies. [EventStoreDB-Client-Java#246](https://github.com/EventStore/EventStoreDB-Client-Java/pull/246) - -## [5.0.0] - 2023-10-23 -### Changed -- Improve internal gRPC connection management for better error propagation. [EventStoreDB-Client-Java#226](https://github.com/EventStore/EventStoreDB-Client-Java/pull/226) -- Add secure and cluster tests. [EventStoreDB-Client-Java#236](https://github.com/EventStore/EventStoreDB-Client-Java/pull/236) -- Improve connection string parsing. [EventStoreDB-Client-Java#243](https://github.com/EventStore/EventStoreDB-Client-Java/pull/243) - -### Added -- Support authenticated gossip read request. [EventStoreDB-Client-Java#235](https://github.com/EventStore/EventStoreDB-Client-Java/pull/235) - -### Fixed -- Improve stream metadata serialization. [EventStoreDB-Client-Java#242](https://github.com/EventStore/EventStoreDB-Client-Java/pull/242) - -## [4.3.0] - 2023-07-03 -### Added -- Support user-provided gRPC client interceptors. [EventStoreDB-Client-Java#233](https://github.com/EventStore/EventStoreDB-Client-Java/pull/233) - -## [4.2.0] - 2023-04-27 - -### Fixed -- Do not start discovery process on ABORT gRPC error. [EventStoreDB-Client-Java#219](https://github.com/EventStore/EventStoreDB-Client-Java/pull/219) -- Fix OptionBase authentication code. [EventStoreDB-Client-Java#221](https://github.com/EventStore/EventStoreDB-Client-Java/pull/221) - -### Added -- Provide toString override for public types. [EventStoreDB-Client-Java#218](https://github.com/EventStore/EventStoreDB-Client-Java/pull/218) -- Implement `ExpectedRevision` raw long representation. [EventStoreDB-Client-Java#230](https://github.com/EventStore/EventStoreDB-Client-Java/pull/230) - -### Changed -- Increase max inbound message length. [EventStoreDB-Client-Java#222](https://github.com/EventStore/EventStoreDB-Client-Java/pull/222) - -## [4.1.1] - 2023-03-06 - -### Changed -- Stop using Jackson JsonMapper static instances. [EventStoreDB-Client-Java#217](https://github.com/EventStore/EventStoreDB-Client-Java/pull/217) - -## [4.1.0] - 2023-02-24 - -### Added -- Add specific exceptions when delete stream operation fails. [EventStoreDB-Client-Java#208](https://github.com/EventStore/EventStoreDB-Client-Java/pull/208) -- Implement human-representation for `ExpectedVersion` types. [EventStoreDB-Client-Java#204](https://github.com/EventStore/EventStoreDB-Client-Java/pull/204) - -### Fixed -- Fix server filtering sample code. [EventStoreDB-Client-Java#206](https://github.com/EventStore/EventStoreDB-Client-Java/pull/206) -- Fix `ConnectionSettingsBuilder` when dealing with keep-alive settings. [EventStoreDB-Client-Java#207](https://github.com/EventStore/EventStoreDB-Client-Java/pull/207) -- Fix `tombstoneStream` overload. [EventStoreDB-Client-Java#205](https://github.com/EventStore/EventStoreDB-Client-Java/pull/205) -- No longer store credentials unprotected in memory. [EventStoreDB-Client-Java#214](https://github.com/EventStore/EventStoreDB-Client-Java/pull/214) - -### Changed -- Update gRPC and protobuf version. [EventStoreDB-Client-Java#213](https://github.com/EventStore/EventStoreDB-Client-Java/pull/213) - -## [4.0.0] - 2022-11-01 - -### Fixed -- Fix next expected version when appending to a stream. [EventStoreDB-Client-Java#196](https://github.com/EventStore/EventStoreDB-Client-Java/pull/196) -- Fix condition causing subscribers not to be completed. [EventStoreDB-Client-Java#193](https://github.com/EventStore/EventStoreDB-Client-Java/pull/193) -- Shutdown `GossipClient` after usage. [EventStoreDB-Client-Java#186](https://github.com/EventStore/EventStoreDB-Client-Java/pull/186) -- Fix channel lifecycle behaviour. [EventStoreDB-Client-Java#184](https://github.com/EventStore/EventStoreDB-Client-Java/pull/184) -- Do not shutdown client on leader reconnect attempt. [EventStoreDB-Client-Java#182](https://github.com/EventStore/EventStoreDB-Client-Java/pull/182) -- Fix error signals to the `GrpcClient` based on a `CompletableFuture`. [EventStoreDB-Client-Java#182](https://github.com/EventStore/EventStoreDB-Client-Java/pull/182) - -### Changed -- Fix next expected version when appending to a stream. [EventStoreDB-Client-Java#196](https://github.com/EventStore/EventStoreDB-Client-Java/pull/196) -- Add additional logging for connection handling. [EventStoreDB-Client-Java#181](https://github.com/EventStore/EventStoreDB-Client-Java/pull/181) +This changelog is no longer maintained. The information has been moved to the [GitHub release notes](https://github.com/kurrent-io/KurrentDB-Client-Java/releases) page. From fce6b7b953529a60335092a526f52f8484d4ae70 Mon Sep 17 00:00:00 2001 From: Yo Eight Date: Thu, 12 Jun 2025 22:52:00 -0400 Subject: [PATCH 04/18] fix: fix eager name resolution (#328) --- .../kurrent/dbclient/ClientTelemetryTags.java | 4 ++-- .../dbclient/ConnectionSettingsBuilder.java | 9 +++++---- .../java/io/kurrent/dbclient/Endpoint.java | 19 +++++++++++++++++++ .../dbclient/KurrentDBClientSettings.java | 6 +++--- .../kurrent/dbclient/SingleNodeDiscovery.java | 6 +++--- .../resolution/DeferredNodeResolution.java | 8 +++++--- .../resolution/DeprecatedNodeResolution.java | 8 +++++--- .../resolution/FixedSeedsNodeResolution.java | 14 +++++++++++--- .../misc/ParseValidConnectionStringTests.java | 4 ++-- 9 files changed, 55 insertions(+), 23 deletions(-) create mode 100644 src/main/java/io/kurrent/dbclient/Endpoint.java diff --git a/src/main/java/io/kurrent/dbclient/ClientTelemetryTags.java b/src/main/java/io/kurrent/dbclient/ClientTelemetryTags.java index 4c94f0dc..49efc5a1 100644 --- a/src/main/java/io/kurrent/dbclient/ClientTelemetryTags.java +++ b/src/main/java/io/kurrent/dbclient/ClientTelemetryTags.java @@ -36,9 +36,9 @@ Builder withServerTagsFromGrpcChannel(ManagedChannel channel) { Builder withServerTagsFromClientSettings(KurrentDBClientSettings settings) { if (settings == null || !settings.isDnsDiscover()) return this; - InetSocketAddress dns = settings.getHosts()[0]; + Endpoint dns = settings.getHosts()[0]; - return withServerTags(dns.getAddress().toString(), String.valueOf(dns.getPort())); + return withServerTags(dns.getHost(), String.valueOf(dns.getPort())); } private Builder withServerTags(String address, String port) { diff --git a/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java b/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java index df4cfe4e..f71efcea 100644 --- a/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java +++ b/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java @@ -29,7 +29,7 @@ public class ConnectionSettingsBuilder { private boolean _tlsVerifyCert = true; private UserCredentials _defaultCredentials; private ClientCertificate _defaultClientCertificate; - private LinkedList _hosts = new LinkedList<>(); + private LinkedList _hosts = new LinkedList<>(); private long _keepAliveTimeout = Consts.DEFAULT_KEEP_ALIVE_TIMEOUT_IN_MS; private long _keepAliveInterval = Consts.DEFAULT_KEEP_ALIVE_INTERVAL_IN_MS; private Long _defaultDeadline = null; @@ -54,7 +54,7 @@ public KurrentDBClientSettings buildConnectionSettings() { _tlsVerifyCert, _defaultCredentials, _defaultClientCertificate, - _hosts.toArray(new InetSocketAddress[0]), + _hosts.toArray(new Endpoint[0]), _keepAliveTimeout, _keepAliveInterval, _defaultDeadline, @@ -155,14 +155,15 @@ public ConnectionSettingsBuilder defaultClientCertificate(ClientCertificate defa * Adds an endpoint the client will use to connect. */ public ConnectionSettingsBuilder addHost(String host, int port) { - return addHost(new InetSocketAddress(host, port)); + this._hosts.add(new Endpoint(host, port)); + return this; } /** * Adds an endpoint the client will use to connect. */ public ConnectionSettingsBuilder addHost(InetSocketAddress host) { - this._hosts.push(host); + this._hosts.push(new Endpoint(host.getHostName(), host.getPort())); return this; } diff --git a/src/main/java/io/kurrent/dbclient/Endpoint.java b/src/main/java/io/kurrent/dbclient/Endpoint.java new file mode 100644 index 00000000..c1de3fb4 --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/Endpoint.java @@ -0,0 +1,19 @@ +package io.kurrent.dbclient; + +public class Endpoint { + private final String host; + private final int port; + + public Endpoint(String host, int port) { + this.host = host; + this.port = port; + } + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } +} diff --git a/src/main/java/io/kurrent/dbclient/KurrentDBClientSettings.java b/src/main/java/io/kurrent/dbclient/KurrentDBClientSettings.java index 44580d66..fc3c9837 100644 --- a/src/main/java/io/kurrent/dbclient/KurrentDBClientSettings.java +++ b/src/main/java/io/kurrent/dbclient/KurrentDBClientSettings.java @@ -34,7 +34,7 @@ public class KurrentDBClientSettings { private final boolean tlsVerifyCert; private final UserCredentials defaultCredentials; private final ClientCertificate defaultClientCertificate; - private final InetSocketAddress[] hosts; + private final Endpoint[] hosts; private final long keepAliveTimeout; private final long keepAliveInterval; private final Long defaultDeadline; @@ -117,7 +117,7 @@ public ClientCertificate getDefaultClientCertificate() { * The list of endpoints that the client uses to connect. * @return hosts to connect to. */ - public InetSocketAddress[] getHosts() { + public Endpoint[] getHosts() { return hosts; } @@ -177,7 +177,7 @@ public String getTlsCaFile() { boolean tlsVerifyCert, UserCredentials defaultCredentials, ClientCertificate defaultClientCertificate, - InetSocketAddress[] hosts, + Endpoint[] hosts, long keepAliveTimeout, long keepAliveInterval, Long defaultDeadline, diff --git a/src/main/java/io/kurrent/dbclient/SingleNodeDiscovery.java b/src/main/java/io/kurrent/dbclient/SingleNodeDiscovery.java index a0eba2f5..3e28055d 100644 --- a/src/main/java/io/kurrent/dbclient/SingleNodeDiscovery.java +++ b/src/main/java/io/kurrent/dbclient/SingleNodeDiscovery.java @@ -4,14 +4,14 @@ import java.util.concurrent.CompletableFuture; class SingleNodeDiscovery implements Discovery { - private final InetSocketAddress endpoint; + private final Endpoint endpoint; - SingleNodeDiscovery(InetSocketAddress endpoint) { + SingleNodeDiscovery(Endpoint endpoint) { this.endpoint = endpoint; } @Override public CompletableFuture run(ConnectionState state) { - return CompletableFuture.runAsync(() -> state.connect(endpoint)); + return CompletableFuture.runAsync(() -> state.connect(new InetSocketAddress(this.endpoint.getHost(), this.endpoint.getPort()))); } } \ No newline at end of file diff --git a/src/main/java/io/kurrent/dbclient/resolution/DeferredNodeResolution.java b/src/main/java/io/kurrent/dbclient/resolution/DeferredNodeResolution.java index fece6c9b..337239b1 100644 --- a/src/main/java/io/kurrent/dbclient/resolution/DeferredNodeResolution.java +++ b/src/main/java/io/kurrent/dbclient/resolution/DeferredNodeResolution.java @@ -1,18 +1,20 @@ package io.kurrent.dbclient.resolution; +import io.kurrent.dbclient.Endpoint; + import java.net.InetSocketAddress; import java.util.Collections; import java.util.List; public class DeferredNodeResolution implements NodeResolution { - private final InetSocketAddress address; + private final Endpoint address; - public DeferredNodeResolution(InetSocketAddress address) { + public DeferredNodeResolution(Endpoint address) { this.address = address; } @Override public List resolve() { - return Collections.singletonList(address); + return Collections.singletonList(new InetSocketAddress(address.getHost(), address.getPort())); } } diff --git a/src/main/java/io/kurrent/dbclient/resolution/DeprecatedNodeResolution.java b/src/main/java/io/kurrent/dbclient/resolution/DeprecatedNodeResolution.java index 774f9417..be343fb6 100644 --- a/src/main/java/io/kurrent/dbclient/resolution/DeprecatedNodeResolution.java +++ b/src/main/java/io/kurrent/dbclient/resolution/DeprecatedNodeResolution.java @@ -1,5 +1,7 @@ package io.kurrent.dbclient.resolution; +import io.kurrent.dbclient.Endpoint; + import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.UnknownHostException; @@ -8,16 +10,16 @@ import java.util.stream.Collectors; public class DeprecatedNodeResolution implements NodeResolution { - private final InetSocketAddress address; + private final Endpoint address; - public DeprecatedNodeResolution(InetSocketAddress address) { + public DeprecatedNodeResolution(Endpoint address) { this.address = address; } @Override public List resolve() { try { - return Arrays.stream(InetAddress.getAllByName(address.getHostName())) + return Arrays.stream(InetAddress.getAllByName(address.getHost())) .map(addr -> new InetSocketAddress(addr, address.getPort())) .collect(Collectors.toList()); } catch (UnknownHostException e) { diff --git a/src/main/java/io/kurrent/dbclient/resolution/FixedSeedsNodeResolution.java b/src/main/java/io/kurrent/dbclient/resolution/FixedSeedsNodeResolution.java index 09c0cf44..3118a76f 100644 --- a/src/main/java/io/kurrent/dbclient/resolution/FixedSeedsNodeResolution.java +++ b/src/main/java/io/kurrent/dbclient/resolution/FixedSeedsNodeResolution.java @@ -1,18 +1,26 @@ package io.kurrent.dbclient.resolution; +import io.kurrent.dbclient.Endpoint; + import java.net.InetSocketAddress; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class FixedSeedsNodeResolution implements NodeResolution { - private final InetSocketAddress[] seeds; + private final Endpoint[] seeds; - public FixedSeedsNodeResolution(InetSocketAddress[] seeds) { + public FixedSeedsNodeResolution(Endpoint[] seeds) { this.seeds = seeds; } @Override public List resolve() { - return Arrays.asList(seeds); + List addresses = new ArrayList<>(seeds.length); + + for (Endpoint seed : seeds) + addresses.add(new InetSocketAddress(seed.getHost(), seed.getPort())); + + return addresses; } } diff --git a/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java b/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java index 8000293f..888b6a76 100644 --- a/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java +++ b/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java @@ -145,7 +145,7 @@ public void assertEquals(KurrentDBClientSettings settings, KurrentDBClientSettin Assertions.assertEquals(settings.getHosts().length, other.getHosts().length); IntStream.range(0, settings.getHosts().length).forEach((i) -> { - Assertions.assertEquals(settings.getHosts()[i].getHostName(), other.getHosts()[i].getHostName()); + Assertions.assertEquals(settings.getHosts()[i].getHost(), other.getHosts()[i].getHost()); Assertions.assertEquals(settings.getHosts()[i].getPort(), other.getHosts()[i].getPort()); }); } @@ -227,7 +227,7 @@ private KurrentDBClientSettings parseJson(String input) throws JsonProcessingExc } tree.get("hosts").elements().forEachRemaining((host) -> { - builder.addHost(new InetSocketAddress(host.get("address").asText(), host.get("port").asInt())); + builder.addHost(host.get("address").asText(), host.get("port").asInt()); }); if (tree.get("features") != null) { From 987b6abb9d4a10a166434bd97dcfa6908d59dceb Mon Sep 17 00:00:00 2001 From: William Chong Date: Fri, 13 Jun 2025 16:58:44 +0400 Subject: [PATCH 05/18] Prepare 1.0.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index b06e3ba9..6c2124a8 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ tasks.withType(JavaCompile) { } group = 'io.kurrent' -version = '1.0.1' +version = '1.0.2' java { withSourcesJar() From a3f02ae37bc0b267e709b8d86328c82409078805 Mon Sep 17 00:00:00 2001 From: William Chong Date: Mon, 7 Jul 2025 12:58:29 +0400 Subject: [PATCH 06/18] fix: skip tracing metadata injection when span context is invalid or unsampled (#331) --- .../io/kurrent/dbclient/ClientTelemetry.java | 3 + .../kurrent/dbclient/streams/AppendTests.java | 61 +++++++++---------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/src/main/java/io/kurrent/dbclient/ClientTelemetry.java b/src/main/java/io/kurrent/dbclient/ClientTelemetry.java index 4d180053..e435bc93 100644 --- a/src/main/java/io/kurrent/dbclient/ClientTelemetry.java +++ b/src/main/java/io/kurrent/dbclient/ClientTelemetry.java @@ -29,6 +29,9 @@ private static Tracer getTracer() { } private static List tryInjectTracingContext(Span span, List events) { + if (!span.getSpanContext().isValid() || !span.getSpanContext().isSampled()) + return events; + List injectedEvents = new ArrayList<>(); for (EventData event : events) { boolean isJsonEvent = Objects.equals(event.getContentType(), ContentType.JSON); diff --git a/src/test/java/io/kurrent/dbclient/streams/AppendTests.java b/src/test/java/io/kurrent/dbclient/streams/AppendTests.java index 72701fd0..3ed125a9 100644 --- a/src/test/java/io/kurrent/dbclient/streams/AppendTests.java +++ b/src/test/java/io/kurrent/dbclient/streams/AppendTests.java @@ -1,7 +1,7 @@ package io.kurrent.dbclient.streams; +import com.fasterxml.jackson.databind.node.ObjectNode; import io.kurrent.dbclient.*; -import com.fasterxml.jackson.databind.json.JsonMapper; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -11,43 +11,42 @@ public interface AppendTests extends ConnectionAware { @Test default void testAppendSingleEventNoStream() throws Throwable { KurrentDBClient client = getDatabase().defaultClient(); - - final String streamName = generateName(); - final String eventType = "TestEvent"; - final String eventId = "38fffbc2-339e-11ea-8c7b-784f43837872"; - final byte[] eventMetaData = new byte[]{0xd, 0xe, 0xa, 0xd}; - final JsonMapper jsonMapper = new JsonMapper(); - - EventData event = EventData.builderAsJson(eventType, jsonMapper.writeValueAsBytes(new Foo())) - .metadataAsBytes(eventMetaData) - .eventId(UUID.fromString(eventId)) + String streamName = generateName(); + String eventType = "TestEvent"; + UUID eventId = UUID.randomUUID(); + Foo foo = new Foo(); + byte[] fooBytes = mapper.writeValueAsBytes(foo); + + EventData event = EventData.builderAsJson(eventType, fooBytes) + .metadataAsBytes(fooBytes) + .eventId(eventId) .build(); - AppendToStreamOptions appendOptions = AppendToStreamOptions.get() - .streamState(StreamState.noStream()); - - WriteResult appendResult = client.appendToStream(streamName, appendOptions, event) - .get(); + WriteResult appendResult = client.appendToStream( + streamName, + AppendToStreamOptions.get().streamState(StreamState.noStream()), + event + ).get(); Assertions.assertEquals(StreamState.streamRevision(0), appendResult.getNextExpectedRevision()); - ReadStreamOptions readStreamOptions = ReadStreamOptions.get() - .fromEnd() - .backwards() - .maxCount(1); - - // Ensure appended event is readable - ReadResult result = client.readStream(streamName, readStreamOptions) - .get(); + ReadResult result = client.readStream( + streamName, + ReadStreamOptions.get().fromEnd().backwards().maxCount(1) + ).get(); Assertions.assertEquals(1, result.getEvents().size()); RecordedEvent first = result.getEvents().get(0).getEvent(); - JsonMapper mapper = new JsonMapper(); - - Assertions.assertEquals(streamName, first.getStreamId()); - Assertions.assertEquals(eventType, first.getEventType()); - Assertions.assertEquals(eventId, first.getEventId().toString()); - Assertions.assertArrayEquals(eventMetaData, first.getUserMetadata()); - Assertions.assertEquals(new Foo(), mapper.readValue(first.getEventData(), Foo.class)); + ObjectNode userMetadata = mapper.readValue(first.getUserMetadata(), ObjectNode.class); + + Assertions.assertAll( + () -> Assertions.assertEquals(streamName, first.getStreamId()), + () -> Assertions.assertEquals(eventType, first.getEventType()), + () -> Assertions.assertEquals(eventId.toString(), first.getEventId().toString()), + () -> Assertions.assertEquals(foo, mapper.readValue(first.getEventData(), Foo.class)), + () -> Assertions.assertEquals(foo, mapper.readValue(first.getUserMetadata(), Foo.class)), + () -> Assertions.assertFalse(userMetadata.has(ClientTelemetryConstants.Metadata.TRACE_ID)), + () -> Assertions.assertFalse(userMetadata.has(ClientTelemetryConstants.Metadata.SPAN_ID)) + ); } } From ed1422cd2b8c1c09b7ef17caba845f8c934a6c71 Mon Sep 17 00:00:00 2001 From: William Chong Date: Mon, 7 Jul 2025 12:59:28 +0400 Subject: [PATCH 07/18] Prepare 1.0.3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 6c2124a8..5b51f211 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ tasks.withType(JavaCompile) { } group = 'io.kurrent' -version = '1.0.2' +version = '1.0.3' java { withSourcesJar() From 411c2c2ed4087a63f4f0b06ec3b0218db1a703e6 Mon Sep 17 00:00:00 2001 From: William Chong Date: Thu, 17 Jul 2025 15:24:47 +0400 Subject: [PATCH 08/18] Add cherry pick label workflow --- .github/workflows/cherry-pick-pr-for-label.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/cherry-pick-pr-for-label.yml diff --git a/.github/workflows/cherry-pick-pr-for-label.yml b/.github/workflows/cherry-pick-pr-for-label.yml new file mode 100644 index 00000000..b60bec49 --- /dev/null +++ b/.github/workflows/cherry-pick-pr-for-label.yml @@ -0,0 +1,14 @@ +name: Cherry pick PR commits for label +on: + pull_request_target: + types: [closed] +jobs: + cherry_pick_pr_for_label: + name: Cherry pick PR commits for label + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Cherry Pick PR for label + uses: kurrent-io/Automations/cherry-pick-pr-for-label@master + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file From ac67be03fafbc97b7788e52e3307454ac41be99a Mon Sep 17 00:00:00 2001 From: Yo Eight Date: Mon, 21 Jul 2025 02:16:52 -0400 Subject: [PATCH 09/18] feat: add multi stream append support (#330) --- .github/workflows/ci.yml | 2 +- .github/workflows/load-configuration.yml | 46 ++ .github/workflows/lts.yml | 6 +- .github/workflows/plugins-tests.yml | 12 +- .github/workflows/previous-lts.yml | 2 +- .github/workflows/tests.yml | 29 +- docker-compose.yml | 46 +- .../kurrent/dbclient/AppendStreamFailure.java | 36 ++ .../kurrent/dbclient/AppendStreamRequest.java | 27 + .../kurrent/dbclient/AppendStreamSuccess.java | 21 + .../dbclient/ConnectionSettingsBuilder.java | 2 +- .../kurrent/dbclient/ContentTypeMapper.java | 20 + .../io/kurrent/dbclient/FeatureFlags.java | 1 + .../io/kurrent/dbclient/GossipClient.java | 2 +- .../java/io/kurrent/dbclient/GrpcUtils.java | 10 +- .../io/kurrent/dbclient/KurrentDBClient.java | 4 + .../MultiAppendStreamErrorVisitor.java | 10 + .../dbclient/MultiAppendWriteResult.java | 22 + .../kurrent/dbclient/MultiStreamAppend.java | 107 ++++ .../io/kurrent/dbclient/ServerFeatures.java | 2 + .../io/kurrent/dbclient/ServerVersion.java | 11 + .../kurrent/dbclient/SystemMetadataKeys.java | 2 + .../{ => kurrentdb/protocol/v1}/code.proto | 0 .../{ => kurrentdb/protocol/v1}/gossip.proto | 2 +- .../protocol/v1}/persistent.proto | 2 +- .../protocol/v1}/projectionmanagement.proto | 2 +- .../protocol/v1}/serverfeatures.proto | 2 +- .../{ => kurrentdb/protocol/v1}/shared.proto | 0 .../{ => kurrentdb/protocol/v1}/status.proto | 2 +- .../{ => kurrentdb/protocol/v1}/streams.proto | 4 +- .../proto/kurrentdb/protocol/v2/core.proto | 82 +++ .../protocol/v2/features/service.proto | 144 ++++++ .../protocol/v2/streams/shared.proto | 118 +++++ .../protocol/v2/streams/streams.proto | 481 ++++++++++++++++++ .../dbclient/MultiStreamAppendTests.java | 88 ++++ .../misc/ParseValidConnectionStringTests.java | 2 +- vars.env | 6 +- 37 files changed, 1289 insertions(+), 66 deletions(-) create mode 100644 .github/workflows/load-configuration.yml create mode 100644 src/main/java/io/kurrent/dbclient/AppendStreamFailure.java create mode 100644 src/main/java/io/kurrent/dbclient/AppendStreamRequest.java create mode 100644 src/main/java/io/kurrent/dbclient/AppendStreamSuccess.java create mode 100644 src/main/java/io/kurrent/dbclient/ContentTypeMapper.java create mode 100644 src/main/java/io/kurrent/dbclient/MultiAppendStreamErrorVisitor.java create mode 100644 src/main/java/io/kurrent/dbclient/MultiAppendWriteResult.java create mode 100644 src/main/java/io/kurrent/dbclient/MultiStreamAppend.java rename src/main/proto/{ => kurrentdb/protocol/v1}/code.proto (100%) rename src/main/proto/{ => kurrentdb/protocol/v1}/gossip.proto (94%) rename src/main/proto/{ => kurrentdb/protocol/v1}/persistent.proto (99%) rename src/main/proto/{ => kurrentdb/protocol/v1}/projectionmanagement.proto (98%) rename src/main/proto/{ => kurrentdb/protocol/v1}/serverfeatures.proto (91%) rename src/main/proto/{ => kurrentdb/protocol/v1}/shared.proto (100%) rename src/main/proto/{ => kurrentdb/protocol/v1}/status.proto (97%) rename src/main/proto/{ => kurrentdb/protocol/v1}/streams.proto (98%) create mode 100644 src/main/proto/kurrentdb/protocol/v2/core.proto create mode 100644 src/main/proto/kurrentdb/protocol/v2/features/service.proto create mode 100644 src/main/proto/kurrentdb/protocol/v2/streams/shared.proto create mode 100644 src/main/proto/kurrentdb/protocol/v2/streams/streams.proto create mode 100644 src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9dba48c9..5a4d4f68 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,5 +15,5 @@ jobs: name: Tests (CI) uses: ./.github/workflows/tests.yml with: - image: ${{ fromJSON(vars.KURRENTDB_DOCKER_IMAGES).ci.fullname }} + runtime: ci secrets: inherit diff --git a/.github/workflows/load-configuration.yml b/.github/workflows/load-configuration.yml new file mode 100644 index 00000000..a2995585 --- /dev/null +++ b/.github/workflows/load-configuration.yml @@ -0,0 +1,46 @@ +name: Load KurrentDB Runtime Configuration +on: + workflow_call: + inputs: + runtime: + description: "The runtime's name. Current options are: `ci`, `previous-lts`, `latest`" + type: string + + outputs: + runtime: + description: The runtime's name + value: ${{ inputs.runtime }} + + registry: + description: The Docker registry + value: ${{ jobs.load.outputs.registry }} + + image: + description: The Docker image + value: ${{ jobs.load.outputs.image }} + + tag: + description: The Docker image tag + value: ${{ jobs.load.outputs.tag }} + + full_image_name: + description: The full Docker image name (including registry, image, and tag) + value: ${{ jobs.load.outputs.full_image_name }} + +jobs: + load: + runs-on: ubuntu-latest + outputs: + registry: ${{ steps.set.outputs.registry }} + image: ${{ steps.set.outputs.image }} + tag: ${{ steps.set.outputs.tag }} + full_image_name: ${{ steps.set.outputs.full_image_name }} + + steps: + - name: Set KurrentDB Runtime Configuration Properties + id: set + run: | + echo "registry=${{ fromJSON(vars.KURRENTDB_DOCKER_IMAGES)[inputs.runtime].registry }}" >> $GITHUB_OUTPUT + echo "tag=${{ fromJSON(vars.KURRENTDB_DOCKER_IMAGES)[inputs.runtime].tag }}" >> $GITHUB_OUTPUT + echo "image=${{ fromJSON(vars.KURRENTDB_DOCKER_IMAGES)[inputs.runtime].image }}" >> $GITHUB_OUTPUT + echo "full_image_name=${{ fromJSON(vars.KURRENTDB_DOCKER_IMAGES)[inputs.runtime].fullname }}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/lts.yml b/.github/workflows/lts.yml index c0936f87..4b1fc04b 100644 --- a/.github/workflows/lts.yml +++ b/.github/workflows/lts.yml @@ -15,7 +15,7 @@ jobs: name: Tests (LTS) uses: ./.github/workflows/tests.yml with: - image: ${{ fromJSON(vars.KURRENTDB_DOCKER_IMAGES).lts.fullname }} + runtime: lts secrets: inherit # Will be removed in the future @@ -24,5 +24,7 @@ jobs: uses: ./.github/workflows/plugins-tests.yml with: - image: "docker.eventstore.com/eventstore-ee/eventstoredb-commercial:24.2.0-jammy" + registry: docker.eventstore.com/eventstore-ee + image: eventstoredb-commercial + tag: 24.2.0-jammy secrets: inherit diff --git a/.github/workflows/plugins-tests.yml b/.github/workflows/plugins-tests.yml index 08aed4c8..fed0338a 100644 --- a/.github/workflows/plugins-tests.yml +++ b/.github/workflows/plugins-tests.yml @@ -3,9 +3,15 @@ name: enterprise plugins tests workflow on: workflow_call: inputs: + registry: + required: true + type: string image: required: true type: string + tag: + required: true + type: string jobs: single_node: @@ -46,7 +52,7 @@ jobs: - name: Execute Gradle build run: ./gradlew ci --tests ${{ matrix.test }}Tests env: - KURRENTDB_IMAGE: ${{ inputs.image }} + KURRENTDB_IMAGE: ${{inputs.registry}}/${{ inputs.image }}:${{ inputs.tag }} SECURE: true - uses: actions/upload-artifact@v4 @@ -81,7 +87,9 @@ jobs: - name: Set up cluster with Docker Compose run: docker compose up -d env: - KURRENTDB_IMAGE: ${{ inputs.image }} + KURRENTDB_DOCKER_REGISTRY: ${{ inputs.registry }} + KURRENTDB_DOCKER_IMAGE: ${{ inputs.image }} + KURRENTDB_DOCKER_TAG: ${{ inputs.tag }} - name: Generate user certificates run: docker compose --file configure-user-certs-for-tests.yml up diff --git a/.github/workflows/previous-lts.yml b/.github/workflows/previous-lts.yml index 0fd060c2..f1941397 100644 --- a/.github/workflows/previous-lts.yml +++ b/.github/workflows/previous-lts.yml @@ -15,5 +15,5 @@ jobs: name: Tests (Previous LTS) uses: ./.github/workflows/tests.yml with: - image: ${{ fromJSON(vars.KURRENTDB_DOCKER_IMAGES)['previous-lts'].fullname }} + runtime: previous-lts secrets: inherit diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 0495aefc..92ce26e8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -3,18 +3,24 @@ name: tests workflow on: workflow_call: inputs: - image: + runtime: required: true type: string jobs: + load_configuration: + uses: ./.github/workflows/load-configuration.yml + with: + runtime: ${{ inputs.runtime }} + single_node: + needs: load_configuration name: Single node strategy: fail-fast: false matrix: - test: [Streams, PersistentSubscriptions, Telemetry] + test: [Streams, PersistentSubscriptions, Telemetry, MultiStreamAppend] runs-on: ubuntu-latest steps: @@ -41,16 +47,10 @@ jobs: - name: Execute Gradle build run: ./gradlew ci --tests ${{ matrix.test }}Tests env: - KURRENTDB_IMAGE: ${{ inputs.image }} - - - uses: actions/upload-artifact@v4 - if: failure() - with: - name: esdb_logs.tar.gz - path: /tmp/esdb_logs.tar.gz - if-no-files-found: error + KURRENTDB_IMAGE: ${{ needs.load_configuration.outputs.full_image_name }} secure: + needs: load_configuration name: Secure strategy: @@ -86,7 +86,7 @@ jobs: - name: Execute Gradle build run: ./gradlew ci --tests ${{ matrix.test }}Tests env: - KURRENTDB_IMAGE: ${{ inputs.image }} + KURRENTDB_IMAGE: ${{ needs.load_configuration.outputs.full_image_name }} SECURE: true - uses: actions/upload-artifact@v4 @@ -96,12 +96,13 @@ jobs: path: /tmp/esdb_logs.tar.gz cluster: + needs: load_configuration name: Cluster strategy: fail-fast: false matrix: - test: [Streams, PersistentSubscriptions] + test: [Streams, PersistentSubscriptions, MultiStreamAppend] runs-on: ubuntu-latest steps: @@ -117,7 +118,9 @@ jobs: - name: Set up cluster with Docker Compose run: docker compose up -d env: - KURRENTDB_IMAGE: ${{ inputs.image }} + KURRENTDB_DOCKER_REGISTRY: ${{ needs.load_configuration.outputs.registry }} + KURRENTDB_DOCKER_IMAGE: ${{ needs.load_configuration.outputs.image }} + KURRENTDB_DOCKER_TAG: ${{ needs.load_configuration.outputs.tag }} - name: Set up JDK 8 uses: actions/setup-java@v3 diff --git a/docker-compose.yml b/docker-compose.yml index e64e7e83..344f19f3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.5" - services: volumes-provisioner: image: hasnat/volumes-provisioner @@ -26,71 +24,57 @@ services: - volumes-provisioner esdb-node1: &template - image: ${KURRENTDB_IMAGE:-docker.kurrent.io/eventstore/eventstoredb-ee:lts} + image: ${KURRENTDB_DOCKER_REGISTRY:-docker.kurrent.io/eventstore}/${KURRENTDB_DOCKER_IMAGE:-eventstoredb-ee}:${KURRENTDB_DOCKER_TAG:-lts} env_file: - vars.env environment: - EVENTSTORE_GOSSIP_SEED=172.30.240.12:2113,172.30.240.13:2113 - - EVENTSTORE_INT_IP=172.30.240.11 - - EVENTSTORE_CERTIFICATE_FILE=/etc/eventstore/certs/node1/node.crt - - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/etc/eventstore/certs/node1/node.key - - EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2111 + - EVENTSTORE_REPLICATION_IP=172.30.240.11 + - EVENTSTORE_CERTIFICATE_FILE=/etc/kurrentdb/certs/node1/node.crt + - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/etc/kurrentdb/certs/node1/node.key + - EVENTSTORE_ADVERTISE_NODE_PORT_TO_CLIENT_AS=2111 ports: - 2111:2113 networks: clusternetwork: ipv4_address: 172.30.240.11 volumes: - - ./certs:/etc/eventstore/certs + - ./certs:/etc/kurrentdb/certs restart: unless-stopped depends_on: - cert-gen esdb-node2: <<: *template - env_file: - - vars.env environment: - EVENTSTORE_GOSSIP_SEED=172.30.240.11:2113,172.30.240.13:2113 - - EVENTSTORE_INT_IP=172.30.240.12 - - EVENTSTORE_CERTIFICATE_FILE=/etc/eventstore/certs/node2/node.crt - - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/etc/eventstore/certs/node2/node.key - - EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2112 + - EVENTSTORE_REPLICATION_IP=172.30.240.12 + - EVENTSTORE_CERTIFICATE_FILE=/etc/kurrentdb/certs/node2/node.crt + - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/etc/kurrentdb/certs/node2/node.key + - EVENTSTORE_ADVERTISE_NODE_PORT_TO_CLIENT_AS=2112 ports: - 2112:2113 networks: clusternetwork: ipv4_address: 172.30.240.12 - volumes: - - ./certs:/etc/eventstore/certs - restart: unless-stopped - depends_on: - - cert-gen esdb-node3: <<: *template - env_file: - - vars.env environment: - EVENTSTORE_GOSSIP_SEED=172.30.240.11:2113,172.30.240.12:2113 - - EVENTSTORE_INT_IP=172.30.240.13 - - EVENTSTORE_CERTIFICATE_FILE=/etc/eventstore/certs/node3/node.crt - - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/etc/eventstore/certs/node3/node.key - - EVENTSTORE_ADVERTISE_HTTP_PORT_TO_CLIENT_AS=2113 + - EVENTSTORE_REPLICATION_IP=172.30.240.13 + - EVENTSTORE_CERTIFICATE_FILE=/etc/kurrentdb/certs/node3/node.crt + - EVENTSTORE_CERTIFICATE_PRIVATE_KEY_FILE=/etc/kurrentdb/certs/node3/node.key + - EVENTSTORE_ADVERTISE_NODE_PORT_TO_CLIENT_AS=2113 ports: - 2113:2113 networks: clusternetwork: ipv4_address: 172.30.240.13 - volumes: - - ./certs:/etc/eventstore/certs - restart: unless-stopped - depends_on: - - cert-gen networks: clusternetwork: - name: eventstoredb.local + name: kurrentdb.local driver: bridge ipam: driver: default diff --git a/src/main/java/io/kurrent/dbclient/AppendStreamFailure.java b/src/main/java/io/kurrent/dbclient/AppendStreamFailure.java new file mode 100644 index 00000000..28218bef --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/AppendStreamFailure.java @@ -0,0 +1,36 @@ +package io.kurrent.dbclient; + +public class AppendStreamFailure { + private final io.kurrentdb.protocol.streams.v2.AppendStreamFailure inner; + + AppendStreamFailure(io.kurrentdb.protocol.streams.v2.AppendStreamFailure inner) { + this.inner = inner; + } + + public String getStreamName() { + return this.inner.getStream(); + } + + public void visit(MultiAppendStreamErrorVisitor visitor) { + if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.STREAM_REVISION_CONFLICT) { + visitor.onWrongExpectedRevision(this.inner.getStreamRevisionConflict().getStreamRevision()); + return; + } + + if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.ACCESS_DENIED) { + visitor.onAccessDenied(this.inner.getAccessDenied()); + } + + if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.STREAM_DELETED) { + visitor.onStreamDeleted(); + return; + } + + if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.TRANSACTION_MAX_SIZE_EXCEEDED) { + visitor.onTransactionMaxSizeExceeded(this.inner.getTransactionMaxSizeExceeded().getMaxSize()); + return; + } + + throw new IllegalArgumentException("Append failure does not match any known error type"); + } +} diff --git a/src/main/java/io/kurrent/dbclient/AppendStreamRequest.java b/src/main/java/io/kurrent/dbclient/AppendStreamRequest.java new file mode 100644 index 00000000..d2c666b3 --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/AppendStreamRequest.java @@ -0,0 +1,27 @@ +package io.kurrent.dbclient; + +import java.util.Iterator; + +public class AppendStreamRequest { + private final String streamName; + private final Iterator events; + private final StreamState expectedState; + + public AppendStreamRequest(String streamName, Iterator events, StreamState expectedState) { + this.streamName = streamName; + this.events = events; + this.expectedState = expectedState; + } + + public String getStreamName() { + return streamName; + } + + public Iterator getEvents() { + return events; + } + + public StreamState getExpectedState() { + return expectedState; + } +} diff --git a/src/main/java/io/kurrent/dbclient/AppendStreamSuccess.java b/src/main/java/io/kurrent/dbclient/AppendStreamSuccess.java new file mode 100644 index 00000000..be55e3ba --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/AppendStreamSuccess.java @@ -0,0 +1,21 @@ +package io.kurrent.dbclient; + +public class AppendStreamSuccess { + private final io.kurrentdb.protocol.streams.v2.AppendStreamSuccess inner; + + AppendStreamSuccess(io.kurrentdb.protocol.streams.v2.AppendStreamSuccess inner) { + this.inner = inner; + } + + public String getStreamName() { + return this.inner.getStream(); + } + + public long getStreamRevision() { + return this.inner.getStreamRevision(); + } + + public long getPosition() { + return this.inner.getPosition(); + } +} diff --git a/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java b/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java index f71efcea..eb159511 100644 --- a/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java +++ b/src/main/java/io/kurrent/dbclient/ConnectionSettingsBuilder.java @@ -17,7 +17,7 @@ public class ConnectionSettingsBuilder { private static final Logger logger = LoggerFactory.getLogger(ConnectionSettingsBuilder.class); private static final Set SUPPORTED_PROTOCOLS = new HashSet<>(Arrays.asList( - "esdb", "esdb+discover", "kurrent", "kurrent+discover", "kdb", "kdb+discover", "kurrentdb", "kurrentdb+discover" + "esdb", "esdb+discover", "kurrentdb", "kurrent+discover", "kdb", "kdb+discover", "kurrentdb", "kurrentdb+discover" )); private boolean _dnsDiscover = false; diff --git a/src/main/java/io/kurrent/dbclient/ContentTypeMapper.java b/src/main/java/io/kurrent/dbclient/ContentTypeMapper.java new file mode 100644 index 00000000..a74bb316 --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/ContentTypeMapper.java @@ -0,0 +1,20 @@ +package io.kurrent.dbclient; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class ContentTypeMapper { + private static final Map CONTENT_TYPE_MAP; + + static { + Map map = new HashMap<>(); + map.put("application/json", "Json"); + map.put("application/octet-stream", "Binary"); + CONTENT_TYPE_MAP = Collections.unmodifiableMap(map); + } + + public static String toSchemaDataFormat(String contentType) { + return CONTENT_TYPE_MAP.getOrDefault(contentType, contentType); + } +} diff --git a/src/main/java/io/kurrent/dbclient/FeatureFlags.java b/src/main/java/io/kurrent/dbclient/FeatureFlags.java index 83e755a5..11b66517 100644 --- a/src/main/java/io/kurrent/dbclient/FeatureFlags.java +++ b/src/main/java/io/kurrent/dbclient/FeatureFlags.java @@ -7,5 +7,6 @@ class FeatureFlags { public final static int PERSISTENT_SUBSCRIPTION_RESTART_SUBSYSTEM = 8; public final static int PERSISTENT_SUBSCRIPTION_GET_INFO = 16; public final static int PERSISTENT_SUBSCRIPTION_TO_ALL = 32; + public final static int MULTI_STREAM_APPEND = 64; public final static int PERSISTENT_SUBSCRIPTION_MANAGEMENT = PERSISTENT_SUBSCRIPTION_LIST | PERSISTENT_SUBSCRIPTION_REPLAY | PERSISTENT_SUBSCRIPTION_GET_INFO | PERSISTENT_SUBSCRIPTION_RESTART_SUBSYSTEM; } diff --git a/src/main/java/io/kurrent/dbclient/GossipClient.java b/src/main/java/io/kurrent/dbclient/GossipClient.java index 3ba89b7c..cd84e5a7 100644 --- a/src/main/java/io/kurrent/dbclient/GossipClient.java +++ b/src/main/java/io/kurrent/dbclient/GossipClient.java @@ -21,7 +21,7 @@ class GossipClient { public GossipClient(KurrentDBClientSettings settings, ManagedChannel channel) { _channel = channel; - _stub = GrpcUtils.configureStub(GossipGrpc.newStub(_channel), settings, new GossipOption(), (long)settings.getGossipTimeout()); + _stub = GrpcUtils.configureStub(GossipGrpc.newStub(_channel), settings, new GossipOption(), settings.getGossipTimeout()); } public void shutdown() { diff --git a/src/main/java/io/kurrent/dbclient/GrpcUtils.java b/src/main/java/io/kurrent/dbclient/GrpcUtils.java index 9dce2240..2779f9b2 100644 --- a/src/main/java/io/kurrent/dbclient/GrpcUtils.java +++ b/src/main/java/io/kurrent/dbclient/GrpcUtils.java @@ -113,10 +113,14 @@ static public StreamsOuterClass.ReadReq.Options.StreamOptions toStreamOptions(St } static public , O> S configureStub(S stub, KurrentDBClientSettings settings, OptionsBase options) { - return configureStub(stub, settings, options, null); + return configureStub(stub, settings, options, null, true); } - static public , O> S configureStub(S stub, KurrentDBClientSettings settings, OptionsBase options, Long forceDeadlineInMs) { + static public , O> S configureStub(S stub, KurrentDBClientSettings settings, OptionsBase options, long forceDeadlineInMs) { + return configureStub(stub, settings, options, forceDeadlineInMs, true); + } + + static public , O> S configureStub(S stub, KurrentDBClientSettings settings, OptionsBase options, Long forceDeadlineInMs, boolean forwardRequiresLeader) { S finalStub = stub; ConnectionMetadata metadata = new ConnectionMetadata(); @@ -146,7 +150,7 @@ static public , O> S configureStub(S stub, Kurren metadata.authenticated(credentials); } - if (options.isLeaderRequired() || settings.getNodePreference() == NodePreference.LEADER) { + if (forwardRequiresLeader && (options.isLeaderRequired() || settings.getNodePreference() == NodePreference.LEADER)) { metadata.requiresLeader(); } diff --git a/src/main/java/io/kurrent/dbclient/KurrentDBClient.java b/src/main/java/io/kurrent/dbclient/KurrentDBClient.java index 22cbe548..3cbea889 100644 --- a/src/main/java/io/kurrent/dbclient/KurrentDBClient.java +++ b/src/main/java/io/kurrent/dbclient/KurrentDBClient.java @@ -75,6 +75,10 @@ public CompletableFuture appendToStream(String streamName, AppendTo return new AppendToStream(this.getGrpcClient(), streamName, events, options).execute(); } + public CompletableFuture multiAppend(AppendToStreamOptions options, Iterator requests) { + return new MultiStreamAppend(this.getGrpcClient(), requests).execute(); + } + /** * Sets a stream's metadata. * @param streamName stream's name. diff --git a/src/main/java/io/kurrent/dbclient/MultiAppendStreamErrorVisitor.java b/src/main/java/io/kurrent/dbclient/MultiAppendStreamErrorVisitor.java new file mode 100644 index 00000000..97b360ff --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/MultiAppendStreamErrorVisitor.java @@ -0,0 +1,10 @@ +package io.kurrent.dbclient; + +import io.kurrentdb.protocol.streams.v2.ErrorDetails; + +public interface MultiAppendStreamErrorVisitor { + default void onWrongExpectedRevision(long streamRevision) {} + default void onAccessDenied(ErrorDetails.AccessDenied detail) {} + default void onStreamDeleted() {} + default void onTransactionMaxSizeExceeded(int maxSize) {} +} diff --git a/src/main/java/io/kurrent/dbclient/MultiAppendWriteResult.java b/src/main/java/io/kurrent/dbclient/MultiAppendWriteResult.java new file mode 100644 index 00000000..ad9f1dad --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/MultiAppendWriteResult.java @@ -0,0 +1,22 @@ +package io.kurrent.dbclient; + +import java.util.List; +import java.util.Optional; + +public class MultiAppendWriteResult { + private final List successes; + private final List failures; + + public MultiAppendWriteResult(List successes, List failures) { + this.successes = successes; + this.failures = failures; + } + + public Optional> getSuccesses() { + return Optional.ofNullable(successes); + } + + public Optional> getFailures() { + return Optional.ofNullable(failures); + } +} diff --git a/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java b/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java new file mode 100644 index 00000000..9c434a7b --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java @@ -0,0 +1,107 @@ +package io.kurrent.dbclient; + +import com.google.protobuf.ByteString; +import io.grpc.Metadata; +import io.grpc.StatusRuntimeException; +import io.grpc.stub.StreamObserver; +import io.kurrentdb.protocol.DynamicValue; +import io.kurrentdb.protocol.streams.v2.AppendRecord; +import io.kurrentdb.protocol.streams.v2.MultiStreamAppendResponse; +import io.kurrentdb.protocol.streams.v2.StreamsServiceGrpc; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +class MultiStreamAppend { + private final GrpcClient client; + private final Iterator requests; + + public MultiStreamAppend(GrpcClient client, Iterator requests) { + this.client = client; + this.requests = requests; + } + + public CompletableFuture execute() { + return this.client.runWithArgs(this::append); + } + + private CompletableFuture append(WorkItemArgs args) { + CompletableFuture result = new CompletableFuture<>(); + + if (!args.supportFeature(FeatureFlags.MULTI_STREAM_APPEND)) { + result.completeExceptionally(new UnsupportedOperationException("Multi-stream append is not supported by the server")); + return result; + } + + StreamsServiceGrpc.StreamsServiceStub client = GrpcUtils.configureStub(StreamsServiceGrpc.newStub(args.getChannel()), this.client.getSettings(), new OptionsBase<>(), null, false); + StreamObserver requestStream = client.multiStreamAppendSession(GrpcUtils.convertSingleResponse(result, this::onResponse)); + + try { + while (this.requests.hasNext()) { + AppendStreamRequest request = this.requests.next(); + io.kurrentdb.protocol.streams.v2.AppendStreamRequest.Builder builder = io.kurrentdb.protocol.streams.v2.AppendStreamRequest.newBuilder() + .setStream(request.getStreamName()); + + while (request.getEvents().hasNext()) { + EventData event = request.getEvents().next(); + builder.addRecords(AppendRecord.newBuilder() + .setData(ByteString.copyFrom(event.getEventData())) + .setRecordId(event.getEventId().toString()) + .putProperties(SystemMetadataKeys.DATA_FORMAT, DynamicValue + .newBuilder() + .setStringValue(ContentTypeMapper.toSchemaDataFormat(event.getContentType())) + .build()) + .putProperties(SystemMetadataKeys.SCHEMA_NAME, DynamicValue + .newBuilder() + .setStringValue(event.getEventType()) + .build()) + .build()); + } + + requestStream.onNext(builder.build()); + } + + requestStream.onCompleted(); + } catch (StatusRuntimeException e) { + String leaderHost = e.getTrailers().get(Metadata.Key.of("leader-endpoint-host", Metadata.ASCII_STRING_MARSHALLER)); + String leaderPort = e.getTrailers().get(Metadata.Key.of("leader-endpoint-port", Metadata.ASCII_STRING_MARSHALLER)); + + if (leaderHost != null && leaderPort != null) { + NotLeaderException reason = new NotLeaderException(leaderHost, Integer.valueOf(leaderPort)); + requestStream.onError(reason); + result.completeExceptionally(reason); + } else { + requestStream.onError(e); + result.completeExceptionally(e); + } + } catch (RuntimeException e) { + requestStream.onError(e); + result.completeExceptionally(e); + } + + return result; + } + + public MultiAppendWriteResult onResponse(MultiStreamAppendResponse response) { + List failures = null; + List successes = null; + + if (response.hasFailure()) { + failures = new ArrayList<>(response.getFailure().getOutputCount()); + + for (io.kurrentdb.protocol.streams.v2.AppendStreamFailure failure : response.getFailure().getOutputList()) { + failures.add(new AppendStreamFailure(failure)); + } + } else { + successes = new ArrayList<>(response.getSuccess().getOutputCount()); + + for (io.kurrentdb.protocol.streams.v2.AppendStreamSuccess success : response.getSuccess().getOutputList()) { + successes.add(new AppendStreamSuccess(success)); + } + } + + return new MultiAppendWriteResult(successes, failures); + } +} diff --git a/src/main/java/io/kurrent/dbclient/ServerFeatures.java b/src/main/java/io/kurrent/dbclient/ServerFeatures.java index 12d377c4..4943c187 100644 --- a/src/main/java/io/kurrent/dbclient/ServerFeatures.java +++ b/src/main/java/io/kurrent/dbclient/ServerFeatures.java @@ -95,6 +95,8 @@ private static CompletableFuture getSupportedFeaturesInternal(Server default: break; } + } else if (method.getMethodName().equals("multistreamappendsession")) { + features |= FeatureFlags.MULTI_STREAM_APPEND; } } diff --git a/src/main/java/io/kurrent/dbclient/ServerVersion.java b/src/main/java/io/kurrent/dbclient/ServerVersion.java index f61f9a1d..64c16d69 100644 --- a/src/main/java/io/kurrent/dbclient/ServerVersion.java +++ b/src/main/java/io/kurrent/dbclient/ServerVersion.java @@ -58,6 +58,17 @@ public boolean isLessOrEqualThan(int major, int minor) { return true; } + public boolean isGreaterOrEqualThan(int major, int minor) { + int cmp; + if ((cmp = Integer.compare(this.major, major)) != 0) + return cmp > 0; + + if ((cmp = Integer.compare(this.minor, minor)) != 0) + return cmp > 0; + + return true; + } + @Override public String toString() { return "ServerVersion{" + diff --git a/src/main/java/io/kurrent/dbclient/SystemMetadataKeys.java b/src/main/java/io/kurrent/dbclient/SystemMetadataKeys.java index d5ae2cc7..d46a02dc 100644 --- a/src/main/java/io/kurrent/dbclient/SystemMetadataKeys.java +++ b/src/main/java/io/kurrent/dbclient/SystemMetadataKeys.java @@ -5,4 +5,6 @@ class SystemMetadataKeys { static final String CREATED = "created"; static final String IS_JSON = "is-json"; static final String TYPE = "type"; + static final String SCHEMA_NAME = "$schema.name"; + static final String DATA_FORMAT = "$schema.data-format"; } diff --git a/src/main/proto/code.proto b/src/main/proto/kurrentdb/protocol/v1/code.proto similarity index 100% rename from src/main/proto/code.proto rename to src/main/proto/kurrentdb/protocol/v1/code.proto diff --git a/src/main/proto/gossip.proto b/src/main/proto/kurrentdb/protocol/v1/gossip.proto similarity index 94% rename from src/main/proto/gossip.proto rename to src/main/proto/kurrentdb/protocol/v1/gossip.proto index 4faaa61c..94804fe8 100644 --- a/src/main/proto/gossip.proto +++ b/src/main/proto/kurrentdb/protocol/v1/gossip.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package event_store.client.gossip; option java_package = "io.kurrent.dbclient.proto.gossip"; -import "shared.proto"; +import "kurrentdb/protocol/v1/shared.proto"; service Gossip { rpc Read (event_store.client.Empty) returns (ClusterInfo); diff --git a/src/main/proto/persistent.proto b/src/main/proto/kurrentdb/protocol/v1/persistent.proto similarity index 99% rename from src/main/proto/persistent.proto rename to src/main/proto/kurrentdb/protocol/v1/persistent.proto index 22762bcd..59ad36a3 100644 --- a/src/main/proto/persistent.proto +++ b/src/main/proto/kurrentdb/protocol/v1/persistent.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package event_store.client.persistent_subscriptions; option java_package = "io.kurrent.dbclient.proto.persistentsubscriptions"; -import "shared.proto"; +import "kurrentdb/protocol/v1/shared.proto"; service PersistentSubscriptions { rpc Create (CreateReq) returns (CreateResp); diff --git a/src/main/proto/projectionmanagement.proto b/src/main/proto/kurrentdb/protocol/v1/projectionmanagement.proto similarity index 98% rename from src/main/proto/projectionmanagement.proto rename to src/main/proto/kurrentdb/protocol/v1/projectionmanagement.proto index 88badaa0..b61e940b 100644 --- a/src/main/proto/projectionmanagement.proto +++ b/src/main/proto/kurrentdb/protocol/v1/projectionmanagement.proto @@ -3,7 +3,7 @@ package event_store.client.projections; option java_package = "io.kurrent.dbclient.proto.projections"; import "google/protobuf/struct.proto"; -import "shared.proto"; +import "kurrentdb/protocol/v1/shared.proto"; service Projections { rpc Create (CreateReq) returns (CreateResp); diff --git a/src/main/proto/serverfeatures.proto b/src/main/proto/kurrentdb/protocol/v1/serverfeatures.proto similarity index 91% rename from src/main/proto/serverfeatures.proto rename to src/main/proto/kurrentdb/protocol/v1/serverfeatures.proto index e0bede70..38b1ecff 100644 --- a/src/main/proto/serverfeatures.proto +++ b/src/main/proto/kurrentdb/protocol/v1/serverfeatures.proto @@ -1,7 +1,7 @@ syntax = "proto3"; package event_store.client.server_features; option java_package = "io.kurrent.dbclient.proto.serverfeatures"; -import "shared.proto"; +import "kurrentdb/protocol/v1/shared.proto"; service ServerFeatures { rpc GetSupportedMethods (event_store.client.Empty) returns (SupportedMethods); diff --git a/src/main/proto/shared.proto b/src/main/proto/kurrentdb/protocol/v1/shared.proto similarity index 100% rename from src/main/proto/shared.proto rename to src/main/proto/kurrentdb/protocol/v1/shared.proto diff --git a/src/main/proto/status.proto b/src/main/proto/kurrentdb/protocol/v1/status.proto similarity index 97% rename from src/main/proto/status.proto rename to src/main/proto/kurrentdb/protocol/v1/status.proto index 4bd4614c..2875e016 100644 --- a/src/main/proto/status.proto +++ b/src/main/proto/kurrentdb/protocol/v1/status.proto @@ -17,7 +17,7 @@ syntax = "proto3"; package google.rpc; import "google/protobuf/any.proto"; -import "code.proto"; +import "kurrentdb/protocol/v1/code.proto"; option cc_enable_arenas = true; option go_package = "google.golang.org/genproto/googleapis/rpc/status;status"; diff --git a/src/main/proto/streams.proto b/src/main/proto/kurrentdb/protocol/v1/streams.proto similarity index 98% rename from src/main/proto/streams.proto rename to src/main/proto/kurrentdb/protocol/v1/streams.proto index 4ff613a7..d3c91287 100644 --- a/src/main/proto/streams.proto +++ b/src/main/proto/kurrentdb/protocol/v1/streams.proto @@ -2,8 +2,8 @@ syntax = "proto3"; package event_store.client.streams; option java_package = "io.kurrent.dbclient.proto.streams"; -import "shared.proto"; -import "status.proto"; +import "kurrentdb/protocol/v1/shared.proto"; +import "kurrentdb/protocol/v1/status.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/empty.proto"; import "google/protobuf/timestamp.proto"; diff --git a/src/main/proto/kurrentdb/protocol/v2/core.proto b/src/main/proto/kurrentdb/protocol/v2/core.proto new file mode 100644 index 00000000..b4626652 --- /dev/null +++ b/src/main/proto/kurrentdb/protocol/v2/core.proto @@ -0,0 +1,82 @@ +syntax = "proto3"; + +package kurrentdb.protocol; + +option csharp_namespace = "KurrentDB.Protocol"; +option java_package = "io.kurrentdb.protocol"; +option java_multiple_files = true; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/struct.proto"; +import "google/protobuf/descriptor.proto"; + +//=================================================================== +// Error Annotations +//=================================================================== + +message ErrorAnnotations { + // Identifies the error condition. + string code = 1; + + // Severity of the error. + Severity severity = 2; + + // Human-readable message that describes the error condition. + optional string message = 3; + + enum Severity { + // The error is recoverable, the operation failed but the session can continue. + RECOVERABLE = 0; + // The error is fatal and the session should be terminated. + FATAL = 1; + } +} + +// Extend the MessageOptions to include error information. +extend google.protobuf.MessageOptions { + // Provides additional information about the error condition. + optional ErrorAnnotations error_info = 50000; +} + +//=================================================================== +// Dynamic values map +//=================================================================== + +// Represents a list of dynamically typed values. +message DynamicValueList { + // Repeated property of dynamically typed values. + repeated DynamicValue values = 1; +} + +// Represents a map of dynamically typed values. +message DynamicValueMap { + // A map of string keys to dynamically typed values. + map values = 1; +} + +// Represents a dynamic value +message DynamicValue { + oneof kind { + // Represents a null value. + google.protobuf.NullValue null_value = 1; + // Represents a 32-bit signed integer value. + sint32 int32_value = 2; + // Represents a 64-bit signed integer value. + sint64 int64_value = 3; + // Represents a byte array value. + bytes bytes_value = 4; + // Represents a 64-bit double-precision floating-point value. + double double_value = 5; + // Represents a 32-bit single-precision floating-point value + float float_value = 6; + // Represents a string value. + string string_value = 7; + // Represents a boolean value. + bool boolean_value = 8; + // Represents a timestamp value. + google.protobuf.Timestamp timestamp_value = 9; + // Represents a duration value. + google.protobuf.Duration duration_value = 10; + } +} diff --git a/src/main/proto/kurrentdb/protocol/v2/features/service.proto b/src/main/proto/kurrentdb/protocol/v2/features/service.proto new file mode 100644 index 00000000..4db99a80 --- /dev/null +++ b/src/main/proto/kurrentdb/protocol/v2/features/service.proto @@ -0,0 +1,144 @@ +syntax = "proto3"; + +/** + * KurrentDB Server Features Protocol + * + * This protocol defines services and messages for discovering server features + * in a KurrentDB environment. It enables clients to adapt their behavior based + * on server features, their enablement status, and requirements. + */ +package kurrentdb.protocol.v2; + +option csharp_namespace = "KurrentDB.Protocol.Features.V2"; +option java_package = "io.kurrentdb.protocol.features.v2"; +option java_multiple_files = true; + +import "google/protobuf/timestamp.proto"; +import "kurrentdb/protocol/v2/core.proto"; + +/** + * Service for retrieving information about the server, including features + * and metadata. + */ +service ServerInfoService { + // Retrieves server information and available features + rpc GetServerInfo(ServerInfoRequest) returns (ServerInfoResponse) {} +} + +/** + * Contains server version information, build details, and compatibility requirements. + */ +message ServerMetadata { + // Semantic version of the server software + string version = 1; + + // Build identifier or hash + string build = 2; + + // Minimum client version required for compatibility + string min_compatible_client_version = 3; + + // Unique identifier for this server node + string node_id = 4; +} + +/** + * Request message for retrieving server information. + */ +message ServerInfoRequest { + // Client version making the request + string client_version = 1; + + // Unique client identifier + string client_id = 2; +} + +/** + * Response containing server information. + */ +message ServerInfoResponse { + // Server information and features + ServerInfo info = 1; +} + +/** + * Top-level server information container including metadata + * and available features. + */ +message ServerInfo { + // Server metadata (version, build info, etc.) + ServerMetadata metadata = 1; + + // Features organized by namespace + map features = 2; +} + +/** + * Container for features within a specific namespace. + */ +message FeaturesList { + // Features in this namespace + repeated Feature features = 1; +} + +/** + * Defines a specific server feature with its enablement status, + * requirements, and metadata. + */ +message Feature { + // Unique identifier for this feature + string name = 1; + + // Human-readable description of the feature + optional string description = 2; + + // Whether this feature is currently enabled + bool enabled = 3; + + // Whether this feature is deprecated and may be removed in future versions + bool deprecated = 4; + + // Requirements associated with this feature that clients must satisfy + repeated FeatureRequirement requirements = 5; + + // Whether clients can request changes to this feature's enabled status + bool client_configurable = 6; + + // For temporary features, indicates when the feature will no longer be available + optional google.protobuf.Timestamp available_until = 7; +} + +/** + * Defines a requirement that must be satisfied to use a feature. + * Requirements can be optional, required, or prohibited. + */ +message FeatureRequirement { + // Unique identifier for this requirement + string name = 1; + + // The value of this requirement, which can contain various data types + DynamicValue value = 2; + + // Enforcement level for this requirement + PolicyStatus policy_status = 3; + + // Human-readable description of the requirement + optional string description = 4; + + // Message shown when the requirement is violated + optional string violation_message = 5; +} + +/** + * Defines how requirements are enforced. + */ +enum PolicyStatus { + // Feature is optional with no warnings + OPTIONAL = 0; + + // Feature must be enabled; operations rejected if disabled + REQUIRED = 3; + + // Feature must be disabled; operations rejected if enabled + PROHIBITED = 4; +} diff --git a/src/main/proto/kurrentdb/protocol/v2/streams/shared.proto b/src/main/proto/kurrentdb/protocol/v2/streams/shared.proto new file mode 100644 index 00000000..e70ba804 --- /dev/null +++ b/src/main/proto/kurrentdb/protocol/v2/streams/shared.proto @@ -0,0 +1,118 @@ +syntax = "proto3"; + +package kurrentdb.protocol.v2; + +option csharp_namespace = "KurrentDB.Protocol.Streams.V2"; +option java_package = "io.kurrentdb.protocol.streams.v2"; +option java_multiple_files = true; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/descriptor.proto"; +import "kurrentdb/protocol/v2/core.proto"; + +// ErrorDetails provides detailed information about specific error conditions. +message ErrorDetails { + // When the user does not have sufficient permissions to perform the + // operation. + message AccessDenied { + option (error_info) = { + code : "ACCESS_DENIED", + severity : RECOVERABLE, + message : "The user does not have sufficient permissions to perform the operation." + }; + } + + // When the stream has been deleted. + message StreamDeleted { + option (error_info) = { + code : "STREAM_DELETED", + severity : RECOVERABLE, + message : "The stream has been soft deleted. It will not be visible in the stream list, until it is restored by appending to it again." + }; + + // The name of the stream that was deleted. + optional string stream = 1; + + // The time when the stream was deleted. + google.protobuf.Timestamp deleted_at = 2; + } + + // When the stream has been tombstoned. + message StreamTombstoned { + option (error_info) = { + code : "STREAM_TOMBSTONED", + severity : RECOVERABLE, + message : "The stream has been tombstoned and cannot be used anymore." + }; + + // The name of the stream that was tombstoned. + optional string stream = 1; + + // The time when the stream was tombstoned. + google.protobuf.Timestamp tombstoned_at = 2; + } + + // When the stream is not found. + message StreamNotFound { + option (error_info) = { + code : "STREAM_NOT_FOUND", + severity : RECOVERABLE, + message : "The specified stream was not found." + }; + + // The name of the stream that was not found. + optional string stream = 1; + } + + // When the expected revision of the stream does not match the actual + // revision. + message StreamRevisionConflict { + option (error_info) = { + code : "REVISION_CONFLICT", + severity : RECOVERABLE, + message : "The actual stream revision does not match the expected revision." + }; + + // The actual revision of the stream. + int64 stream_revision = 1 [jstype = JS_STRING]; + } + + // When the transaction exceeds the maximum size allowed + // (its bigger than the configured chunk size). + message TransactionMaxSizeExceeded { + option (error_info) = { + code : "TRANSACTION_MAX_SIZE_EXCEEDED", + severity : FATAL, + message : "The transaction exceeds the maximum size allowed." + }; + + // The maximum allowed size of the transaction. + uint32 max_size = 1; + } + + // When the user is not found. + message UserNotFound { + option (error_info) = { + code : "USER_NOT_FOUND", + severity : RECOVERABLE, + message : "The specified user was not found." + }; + } + + // When the user is not authenticated. + message NotAuthenticated { + option (error_info) = { + code : "NOT_AUTHENTICATED", + severity : RECOVERABLE, + message : "The user is not authenticated." + }; + } + + message LogPositionNotFound { + option (error_info) = { + code : "LOG_POSITION_NOT_FOUND", + severity : RECOVERABLE, + message : "The specified log position was not found." + }; + } +} diff --git a/src/main/proto/kurrentdb/protocol/v2/streams/streams.proto b/src/main/proto/kurrentdb/protocol/v2/streams/streams.proto new file mode 100644 index 00000000..7fe57056 --- /dev/null +++ b/src/main/proto/kurrentdb/protocol/v2/streams/streams.proto @@ -0,0 +1,481 @@ +syntax = "proto3"; + +package kurrentdb.protocol.v2; + +option csharp_namespace = "KurrentDB.Protocol.Streams.V2"; +option java_package = "io.kurrentdb.protocol.streams.v2"; +option java_multiple_files = true; + +import "google/protobuf/timestamp.proto"; +import "google/protobuf/duration.proto"; +import "google/protobuf/descriptor.proto"; + +import "kurrentdb/protocol/v2/streams/shared.proto"; +import "kurrentdb/protocol/v2/core.proto"; + +service StreamsService { + // Executes an atomic operation to append records to multiple streams. + // This transactional method ensures that all appends either succeed + // completely, or are entirely rolled back, thereby maintaining strict data + // consistency across all involved streams. + rpc MultiStreamAppend(MultiStreamAppendRequest) returns (MultiStreamAppendResponse); + + // Streaming version of MultiStreamAppend that allows clients to send multiple + // append requests over a single connection. When the stream completes, all + // records are appended transactionally (all succeed or fail together). + // Provides improved efficiency for high-throughput scenarios while + // maintaining the same transactional guarantees. + rpc MultiStreamAppendSession(stream AppendStreamRequest) returns (MultiStreamAppendResponse); + +// // Appends records to a specific stream. +// rpc AppendStream(AppendStreamRequest) returns (AppendStreamResponse); + +// // Append batches of records to a stream continuously, while guaranteeing pipelined +// // requests are processed in order. If any request fails, the session is terminated. +// rpc AppendStreamSession(stream AppendStreamRequest) returns (stream AppendStreamResponse); + +// // Retrieve a batch of records +// rpc ReadStream(ReadRequest) returns (ReadResponse); + + // Retrieve batches of records continuously. + rpc ReadSession(ReadRequest) returns (stream ReadResponse); +} + +//=================================================================== +// Append Operations +//=================================================================== + +// Record to be appended to a stream. +message AppendRecord { + // Universally Unique identifier for the record. + // If not provided, the server will generate a new one. + optional string record_id = 1; + +// // The name of the stream to append the record to. +// optional string stream = 6; +// +// // The name of the schema in the registry that defines the structure of the record. +// string schema_name = 4; +// +// // The format of the data in the record. +// SchemaDataFormat data_format = 5; + + // A collection of properties providing additional information about the + // record. This can include user-defined metadata or system properties. + // System properties are prefixed with "$." to avoid conflicts with user-defined properties. + // For example, "$schema.name" or "$schema.data-format". + map properties = 2; + + // The actual data payload of the record, stored as bytes. + bytes data = 3; +} + +// Constants that match the expected state of a stream during an +// append operation. It can be used to specify whether the stream should exist, +// not exist, or can be in any state. +enum ExpectedRevisionConstants { + // The stream should exist and the expected revision should match the current + EXPECTED_REVISION_CONSTANTS_SINGLE_EVENT = 0; + // It is not important whether the stream exists or not. + EXPECTED_REVISION_CONSTANTS_ANY = -2; + // The stream should not exist. If it does, the append will fail. + EXPECTED_REVISION_CONSTANTS_NO_STREAM = -1; + // The stream should exist + EXPECTED_REVISION_CONSTANTS_EXISTS = -4; +} + +// Represents the input for appending records to a specific stream. +message AppendStreamRequest { + // The name of the stream to append records to. + string stream = 1; + // The records to append to the stream. + repeated AppendRecord records = 2; + // The expected revision of the stream. If the stream's current revision does + // not match, the append will fail. + // The expected revision can also be one of the special values + // from ExpectedRevisionConstants. + // Missing value means no expectation, the same as EXPECTED_REVISION_CONSTANTS_ANY + optional sint64 expected_revision = 3 [jstype = JS_STRING]; +} + +// Success represents the successful outcome of an append operation. +message AppendStreamSuccess { + // The name of the stream to which records were appended. + string stream = 1; + // The position of the last appended record in the stream. + int64 position = 2 [jstype = JS_STRING]; + // The expected revision of the stream after the append operation. + int64 stream_revision = 3 [jstype = JS_STRING]; +} + +// Failure represents the detailed error information when an append operation fails. +message AppendStreamFailure { + // The name of the stream to which records were appended. + string stream = 1; + + // The error details + oneof error { + // Failed because the actual stream revision didn't match the expected revision. + ErrorDetails.StreamRevisionConflict stream_revision_conflict = 2; + // Failed because the client lacks sufficient permissions. + ErrorDetails.AccessDenied access_denied = 3; + // Failed because the target stream has been deleted. + ErrorDetails.StreamDeleted stream_deleted = 4; + // Failed because the stream was not found. + ErrorDetails.StreamNotFound stream_not_found = 5; + // Failed because the transaction exceeded the maximum size allowed + ErrorDetails.TransactionMaxSizeExceeded transaction_max_size_exceeded = 6; + } +} + +// AppendStreamResponse represents the output of appending records to a specific +// stream. +message AppendStreamResponse { + // The result of the append operation. + oneof result { + // Success represents the successful outcome of an append operation. + AppendStreamSuccess success = 1; + // Failure represents the details of a failed append operation. + AppendStreamFailure failure = 2; + } +} + +// MultiStreamAppendRequest represents a request to append records to multiple streams. +message MultiStreamAppendRequest { + // A list of AppendStreamInput messages, each representing a stream to which records should be appended. + repeated AppendStreamRequest input = 1; +} + +// Response from the MultiStreamAppend operation. +message MultiStreamAppendResponse { + oneof result { + // Success represents the successful outcome of a multi-stream append operation. + Success success = 1; + // Failure represents the details of a failed multi-stream append operation. + Failure failure = 2; + } + + message Success { + repeated AppendStreamSuccess output = 1; + } + + message Failure { + repeated AppendStreamFailure output = 1; + } +} + +//=================================================================== +// Read Operations +//=================================================================== + +// The scope of the read filter determines where the filter will be applied. +enum ReadFilterScope { + READ_FILTER_SCOPE_UNSPECIFIED = 0; + // The filter will be applied to the record stream name + READ_FILTER_SCOPE_STREAM = 1; + // The filter will be applied to the record schema name + READ_FILTER_SCOPE_SCHEMA_NAME = 2; + // The filter will be applied to the properties of the record + READ_FILTER_SCOPE_PROPERTIES = 3; + // The filter will be applied to all the record properties + // including the stream and schema name + READ_FILTER_SCOPE_RECORD = 4; +} + +// The filter to apply when reading records from the database +// The combination of stream scope and literal expression indicates a direct stream name match, +// while a regex expression indicates a pattern match across multiple streams. +message ReadFilter { + // The scope of the filter. + ReadFilterScope scope = 1; + // The expression can be a regular expression or a literal value. + // If it starts with "~" it will be considered a regex. + string expression = 2; + + // // The optional name of the record property to filter on. + // optional string property_name = 3; + + // The optional property names to filter on. + repeated string property_names = 4; +} + +// Record retrieved from the database. +message Record { + // The unique identifier of the record in the database. + string record_id = 1; + // The position of the record in the database. + int64 position = 5 [jstype = JS_STRING]; + // The actual data payload of the record, stored as bytes. + bytes data = 2; + // Additional information about the record. + map properties = 3; + // When the record was created. + google.protobuf.Timestamp timestamp = 4; + // The stream to which the record belongs. + optional string stream = 6; + // The revision of the stream created when the record was appended. + optional int64 stream_revision = 7 [jstype = JS_STRING]; +} + +// The direction in which to read records from the database (forwards or backwards). +enum ReadDirection { + READ_DIRECTION_FORWARDS = 0; + READ_DIRECTION_BACKWARDS = 1; +} + +// The position from which to start reading records. +// This can be either the earliest or latest position in the stream. +enum ReadPositionConstants { + READ_POSITION_CONSTANTS_UNSPECIFIED = 0; + READ_POSITION_CONSTANTS_EARLIEST = 1; + READ_POSITION_CONSTANTS_LATEST = 2; +} + +// Represents the successful outcome of a read operation. +message ReadSuccess { + repeated Record records = 1; +} + +// Represents the detailed error information when a read operation fails. +message ReadFailure { + // The error details + oneof error { + // Failed because the client lacks sufficient permissions. + ErrorDetails.AccessDenied access_denied = 1; + // Failed because the target stream has been deleted. + ErrorDetails.StreamDeleted stream_deleted = 2; + // Failed because the expected stream revision did not match the actual revision. + ErrorDetails.StreamNotFound stream_not_found = 3; + } +} + +message ReadRequest { + // The filter to apply when reading records. + optional ReadFilter filter = 1; + // The starting position of the log from which to read records. + optional int64 start_position = 2 [jstype = JS_STRING]; + // Limit how many records can be returned. + // This will get capped at the default limit, + // which is up to 1000 records. + optional int64 limit = 3 [jstype = JS_STRING]; + // The direction in which to read the stream (forwards or backwards). + ReadDirection direction = 4; + // Heartbeats can be enabled to monitor end-to-end session health. + HeartbeatOptions heartbeats = 5; + // The number of records to read in a single batch. + int32 batch_size = 6; +} + +//message SubscriptionConfirmed { +// // The subscription ID that was confirmed. +// string subscription_id = 1; +// // The position of the last record read by the server. +// optional int64 position = 2 [jstype = JS_STRING]; +// // When the subscription was confirmed. +// google.protobuf.Timestamp timestamp = 3; +//} + +// Read session response. +message ReadResponse { + oneof result { + // Success represents the successful outcome of an read operation. + ReadSuccess success = 1; + // Failure represents the details of a failed read operation. + ReadFailure failure = 2; + // Heartbeat represents the health check of the read operation when + // the server has not found any records matching the filter for the specified + // period of time or records threshold. + // A heartbeat will be sent when the initial switch to real-time tailing happens. + Heartbeat heartbeat = 3; + } +} + +// A health check will be sent when the server has not found any records +// matching the filter for the specified period of time or records threshold. A +// heartbeat will be sent when the initial switch to real-time tailing happens. +message HeartbeatOptions { + bool enable = 1; + optional google.protobuf.Duration period = 2; // 30 seconds + optional int32 records_threshold = 3; // 500 +} + +enum HeartbeatType { + HEARTBEAT_TYPE_UNSPECIFIED = 0; + HEARTBEAT_TYPE_CHECKPOINT = 1; + HEARTBEAT_TYPE_CAUGHT_UP = 2; + HEARTBEAT_TYPE_FELL_BEHIND = 3; +} + +message Heartbeat { + // This indicates whether the subscription is caught up, fell behind, or + // the filter has not been satisfied after a period of time or records threshold. + HeartbeatType type = 1; + // Checkpoint for resuming reads. + // It will always be populated unless the database is empty. + int64 position = 2 [jstype = JS_STRING]; + // When the heartbeat was sent. + google.protobuf.Timestamp timestamp = 3; +} + +////=================================================================== +//// Read Operations +////=================================================================== +// +//enum ConsumeFilterScope { +// CONSUME_FILTER_SCOPE_UNSPECIFIED = 0; +// // The filter will be applied to the stream name +// CONSUME_FILTER_SCOPE_STREAM = 1; +// // The filter will be applied to the record schema name +// CONSUME_FILTER_SCOPE_RECORD = 2; +// // The filter will be applied to the properties of record +// CONSUME_FILTER_SCOPE_PROPERTIES = 3; +// // The filter will be applied to the record data +// CONSUME_FILTER_SCOPE_DATA = 4; +//} +// +//// The filter to apply when reading records from the database +//// It applies to a stream or a record +//message ConsumeFilter { +// // The scope of the filter. +// ConsumeFilterScope scope = 1; +// // The expression can be a regular expression, a jsonpath expression, or a literal value. +// // if it starts with "~" it will be considered a regex and if it starts with "$" it will be considered a jsonpath filter, else its a literal. +// string expression = 2; +// // The name of the record property to filter on. +// optional string property_name = 3; +//} +// +//// Record retrieved from the database. +//message Record { +// // The unique identifier of the record in the database. +// string record_id = 1; +// // The position of the record in the database. +// int64 position = 5 [jstype = JS_STRING]; +// // The actual data payload of the record, stored as bytes. +// bytes data = 2; +// // Additional information about the record. +// map properties = 3; +// // When the record was created. +// google.protobuf.Timestamp timestamp = 4; +// // The stream to which the record belongs. +// optional string stream = 6; +// // The revision of the stream created when the record was appended. +// optional int64 stream_revision = 7 [jstype = JS_STRING]; +//} +// +////// A batch of records. +////message RecordBatch { +//// repeated Record records = 1; +////} +// +//// The direction in which to read records from the database (forwards or backwards). +//enum ReadDirection { +// READ_DIRECTION_FORWARDS = 0; +// READ_DIRECTION_BACKWARDS = 1; +//} +// +//// The position from which to start reading records. +//// This can be either the earliest or latest position in the stream. +//enum ReadPositionConstants { +// READ_POSITION_CONSTANTS_UNSPECIFIED = 0; +// READ_POSITION_CONSTANTS_EARLIEST = 1; +// READ_POSITION_CONSTANTS_LATEST = 2; +//} +// +//message ReadStreamRequest { +// // The filter to apply when reading records. +// optional ConsumeFilter filter = 1; +// // The starting position of the log from which to read records. +// optional int64 start_position = 2 [jstype = JS_STRING]; +// // Limit how many records can be returned. +// // This will get capped at the default limit, +// // which is up to 1000 records. +// optional int64 limit = 3 [jstype = JS_STRING]; +// // The direction in which to read the stream (forwards or backwards). +// ReadDirection direction = 4; +//} +// +//message ReadStreamSuccess { +// repeated Record records = 1; +//} +// +//// Represents the detailed error information when a read operation fails. +//message ReadStreamFailure { +// // The error details +// oneof error { +// // Failed because the client lacks sufficient permissions. +// ErrorDetails.AccessDenied access_denied = 3; +// // Failed because the target stream has been deleted. +// ErrorDetails.StreamDeleted stream_deleted = 4; +// } +//} +//message ReadStreamResponse { +// // The result of the read operation. +// oneof result { +// // Success represents the successful outcome of an read operation. +// ReadStreamSuccess success = 1; +// // Failure represents the details of a failed read operation. +// ReadStreamFailure failure = 2; +// // Heartbeat represents the health check of the read operation when +// // the server has not found any records matching the filter for the specified +// // period of time or records threshold. +// // A heartbeat will be sent when the initial switch to real-time tailing happens. +// Heartbeat heartbeat = 3; +// } +//} +// +//message ReadSessionRequest { +// // The filter to apply when reading records. +// optional ConsumeFilter filter = 1; +// // The starting position of the log from which to read records. +// optional int64 start_position = 2 [jstype = JS_STRING]; +// // Limit how many records can be returned. +// // This will get capped at the default limit, +// // which is up to 1000 records. +// optional int64 limit = 3 [jstype = JS_STRING]; +// // The direction in which to read the stream (forwards or backwards). +// ReadDirection direction = 4; +// // Heartbeats can be enabled to monitor end-to-end session health. +// HeartbeatOptions heartbeats = 5; +//} +// +//// Read session response. +//message ReadSessionResponse { +// oneof result { +// // Success represents the successful outcome of an read operation. +// ReadStreamSuccess success = 1; +// // Failure represents the details of a failed read operation. +// ReadStreamFailure failure = 2; +// // Heartbeat represents the health check of the read operation when +// // the server has not found any records matching the filter for the specified +// // period of time or records threshold. +// // A heartbeat will be sent when the initial switch to real-time tailing happens. +// Heartbeat heartbeat = 3; +// } +//} +// +//// A health check will be sent when the server has not found any records +//// matching the filter for the specified period of time or records threshold. A +//// heartbeat will be sent when the initial switch to real-time tailing happens. +//message HeartbeatOptions { +// bool enable = 1; +// //optional google.protobuf.Duration period = 2; +// optional int32 records_threshold = 3; // 1000 +//} +// +//enum HeartbeatType { +// HEARTBEAT_TYPE_UNSPECIFIED = 0; +// HEARTBEAT_TYPE_CHECKPOINT = 1; +// HEARTBEAT_TYPE_CAUGHT_UP = 2; +//} +// +//message Heartbeat { +// // This indicates whether the subscription is caught up, fell behind, or +// // the filter has not been satisfied after a period of time or records threshold. +// HeartbeatType type = 1; +// // Checkpoint for resuming reads. +// // It will always be populated unless the database is empty. +// int64 position = 2 [jstype = JS_STRING]; +// // When the heartbeat was sent. +// google.protobuf.Timestamp timestamp = 3; +//} diff --git a/src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java b/src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java new file mode 100644 index 00000000..122ce7ca --- /dev/null +++ b/src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java @@ -0,0 +1,88 @@ +package io.kurrent.dbclient; + +import org.junit.jupiter.api.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.ExecutionException; + +public class MultiStreamAppendTests implements ConnectionAware { + static private Database database; + static private Logger logger; + + @BeforeAll + public static void setup() { + database = DatabaseFactory.spawn(); + logger = LoggerFactory.getLogger(MultiStreamAppendTests.class); + } + + @Override + public Database getDatabase() { + return database; + } + + @Override + public Logger getLogger() { + return logger; + } + + @AfterAll + public static void cleanup() { + database.dispose(); + } + + @Test + public void testMultiStreamAppend() throws ExecutionException, InterruptedException { + KurrentDBClient client = getDefaultClient(); + + Optional version = client.getServerVersion().get(); + + Assumptions.assumeTrue( + version.isPresent() && version.get().isGreaterOrEqualThan(25, 0), + "Multi-stream append is not supported server versions below 25.0.0" + ); + + List requests = new ArrayList<>(); + + List events = new ArrayList<>(); + for (int i = 0; i < 10; i++) + events.add(EventData.builderAsBinary("created", new byte[0]).build()); + + requests.add(new AppendStreamRequest("foobar", events.iterator(), StreamState.any())); + requests.add(new AppendStreamRequest("baz", events.iterator(), StreamState.any())); + + MultiAppendWriteResult result = client.multiAppend(AppendToStreamOptions.get(), requests.iterator()).get(); + + Assertions.assertTrue(result.getSuccesses().isPresent()); + } + + @Test + public void testMultiStreamAppendWhenUnsupported() throws ExecutionException, InterruptedException { + KurrentDBClient client = getDefaultClient(); + + Optional version = client.getServerVersion().get(); + Assumptions.assumeFalse( + version.isPresent() && version.get().isGreaterOrEqualThan(25, 0), + "Multi-stream is supported server versions greater or equal to 25.0.0" + ); + + List requests = new ArrayList<>(); + + List events = new ArrayList<>(); + for (int i = 0; i < 10; i++) + events.add(EventData.builderAsBinary("created", new byte[0]).build()); + + requests.add(new AppendStreamRequest("foobar", events.iterator(), StreamState.any())); + requests.add(new AppendStreamRequest("baz", events.iterator(), StreamState.any())); + + ExecutionException e = Assertions.assertThrows( + ExecutionException.class, + () -> client.multiAppend(AppendToStreamOptions.get(), requests.iterator()).get()); + + Assertions.assertInstanceOf(UnsupportedOperationException.class, e.getCause()); + } +} + diff --git a/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java b/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java index 888b6a76..46fd2a87 100644 --- a/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java +++ b/src/test/java/io/kurrent/dbclient/misc/ParseValidConnectionStringTests.java @@ -18,7 +18,7 @@ public class ParseValidConnectionStringTests { private final JsonMapper mapper = new JsonMapper(); - private static final List PROTOCOLS = Arrays.asList("esdb", "kurrent", "kdb"); + private static final List PROTOCOLS = Arrays.asList("esdb", "kurrentdb", "kdb"); public static Stream validConnectionStrings() { List baseConnectionStrings = Arrays.asList( diff --git a/vars.env b/vars.env index 7883b8c5..a3ecdad9 100644 --- a/vars.env +++ b/vars.env @@ -1,8 +1,8 @@ EVENTSTORE_CLUSTER_SIZE=3 EVENTSTORE_RUN_PROJECTIONS=All -EVENTSTORE_INT_TCP_PORT=1112 -EVENTSTORE_HTTP_PORT=2113 -EVENTSTORE_TRUSTED_ROOT_CERTIFICATES_PATH=/etc/eventstore/certs/ca +EVENTSTORE_REPLICATION_PORT=1112 +EVENTSTORE_NODE_PORT=2113 +EVENTSTORE_TRUSTED_ROOT_CERTIFICATES_PATH=/etc/kurrentdb/certs/ca EVENTSTORE_DISCOVER_VIA_DNS=false EVENTSTORE_ENABLE_ATOM_PUB_OVER_HTTP=true EVENTSTORE_ADVERTISE_HOST_TO_CLIENT_AS=localhost From 709fd4df5b76e1b280eb5c763cc26757bbcf4633 Mon Sep 17 00:00:00 2001 From: William Chong Date: Wed, 23 Jul 2025 11:33:05 +0400 Subject: [PATCH 10/18] Add docs (#332) --- .github/workflows/build-docs.yml | 14 + .github/workflows/tests.yml | 6 + .gitignore | 4 + docs/.eslintignore | 6 + docs/.eslintrc.cjs | 13 + docs/.node-version | 1 + docs/.vuepress/client.ts | 10 + docs/.vuepress/config.ts | 28 + docs/.vuepress/configs/theme.ts | 36 + docs/.vuepress/lib/externalPlaceholders.ts | 6 + docs/.vuepress/lib/log.ts | 12 + docs/.vuepress/lib/types.ts | 18 + docs/.vuepress/lib/version.ts | 15 + docs/.vuepress/lib/versioning.ts | 135 + docs/.vuepress/markdown/linkCheck/index.ts | 90 + docs/.vuepress/markdown/replaceLink/index.ts | 47 + docs/.vuepress/markdown/resolver.ts | 30 + docs/.vuepress/markdown/types.ts | 40 + .../xode/createImportCodeBlockRule.ts | 106 + .../markdown/xode/importCodePlugin.ts | 45 + .../markdown/xode/normalizeWhitespace.ts | 14 + .../markdown/xode/resolveImportCode.ts | 92 + docs/.vuepress/markdown/xode/types.ts | 15 + .../.vuepress/public/Kurrent Logo - Black.svg | 26 + docs/.vuepress/public/Kurrent Logo - Plum.svg | 26 + .../.vuepress/public/Kurrent Logo - White.svg | 26 + docs/.vuepress/public/cloud.png | Bin 0 -> 247451 bytes docs/.vuepress/public/favicon.ico | Bin 0 -> 15406 bytes docs/.vuepress/public/favicon.png | Bin 0 -> 1614 bytes docs/.vuepress/public/fonts/Solina-Bold.woff | Bin 0 -> 17888 bytes docs/.vuepress/public/fonts/Solina-Bold.woff2 | Bin 0 -> 16364 bytes docs/.vuepress/public/fonts/Solina-Light.woff | Bin 0 -> 17804 bytes .../.vuepress/public/fonts/Solina-Light.woff2 | Bin 0 -> 16344 bytes .../.vuepress/public/fonts/Solina-Medium.woff | Bin 0 -> 17684 bytes .../public/fonts/Solina-Medium.woff2 | Bin 0 -> 16148 bytes .../public/fonts/Solina-Regular.woff | Bin 0 -> 17800 bytes .../public/fonts/Solina-Regular.woff2 | Bin 0 -> 16312 bytes docs/.vuepress/public/js/snippet.js | 86 + docs/.vuepress/public/logo-white.png | Bin 0 -> 15352 bytes docs/.vuepress/public/robots.txt | 15 + docs/.vuepress/public/video.png | Bin 0 -> 8640 bytes docs/.vuepress/styles/index.scss | 139 + docs/.vuepress/styles/palette.scss | 193 + docs/api/appending-events.md | 246 + docs/api/authentication.md | 43 + docs/api/delete-stream.md | 48 + docs/api/getting-started.md | 221 + docs/api/observability.md | 182 + docs/api/persistent-subscriptions.md | 268 + docs/api/projections.md | 369 + docs/api/reading-events.md | 388 + docs/api/subscriptions.md | 408 + docs/package.json | 54 + docs/pnpm-lock.yaml | 9767 +++++++++++++++++ docs/tsconfig.json | 13 + 55 files changed, 13301 insertions(+) create mode 100644 .github/workflows/build-docs.yml create mode 100644 docs/.eslintignore create mode 100644 docs/.eslintrc.cjs create mode 100644 docs/.node-version create mode 100644 docs/.vuepress/client.ts create mode 100644 docs/.vuepress/config.ts create mode 100644 docs/.vuepress/configs/theme.ts create mode 100644 docs/.vuepress/lib/externalPlaceholders.ts create mode 100644 docs/.vuepress/lib/log.ts create mode 100644 docs/.vuepress/lib/types.ts create mode 100644 docs/.vuepress/lib/version.ts create mode 100644 docs/.vuepress/lib/versioning.ts create mode 100644 docs/.vuepress/markdown/linkCheck/index.ts create mode 100644 docs/.vuepress/markdown/replaceLink/index.ts create mode 100644 docs/.vuepress/markdown/resolver.ts create mode 100644 docs/.vuepress/markdown/types.ts create mode 100644 docs/.vuepress/markdown/xode/createImportCodeBlockRule.ts create mode 100644 docs/.vuepress/markdown/xode/importCodePlugin.ts create mode 100644 docs/.vuepress/markdown/xode/normalizeWhitespace.ts create mode 100644 docs/.vuepress/markdown/xode/resolveImportCode.ts create mode 100644 docs/.vuepress/markdown/xode/types.ts create mode 100644 docs/.vuepress/public/Kurrent Logo - Black.svg create mode 100644 docs/.vuepress/public/Kurrent Logo - Plum.svg create mode 100644 docs/.vuepress/public/Kurrent Logo - White.svg create mode 100644 docs/.vuepress/public/cloud.png create mode 100644 docs/.vuepress/public/favicon.ico create mode 100644 docs/.vuepress/public/favicon.png create mode 100644 docs/.vuepress/public/fonts/Solina-Bold.woff create mode 100644 docs/.vuepress/public/fonts/Solina-Bold.woff2 create mode 100644 docs/.vuepress/public/fonts/Solina-Light.woff create mode 100644 docs/.vuepress/public/fonts/Solina-Light.woff2 create mode 100644 docs/.vuepress/public/fonts/Solina-Medium.woff create mode 100644 docs/.vuepress/public/fonts/Solina-Medium.woff2 create mode 100644 docs/.vuepress/public/fonts/Solina-Regular.woff create mode 100644 docs/.vuepress/public/fonts/Solina-Regular.woff2 create mode 100644 docs/.vuepress/public/js/snippet.js create mode 100644 docs/.vuepress/public/logo-white.png create mode 100644 docs/.vuepress/public/robots.txt create mode 100644 docs/.vuepress/public/video.png create mode 100644 docs/.vuepress/styles/index.scss create mode 100644 docs/.vuepress/styles/palette.scss create mode 100644 docs/api/appending-events.md create mode 100644 docs/api/authentication.md create mode 100644 docs/api/delete-stream.md create mode 100644 docs/api/getting-started.md create mode 100644 docs/api/observability.md create mode 100644 docs/api/persistent-subscriptions.md create mode 100644 docs/api/projections.md create mode 100644 docs/api/reading-events.md create mode 100644 docs/api/subscriptions.md create mode 100644 docs/package.json create mode 100644 docs/pnpm-lock.yaml create mode 100644 docs/tsconfig.json diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml new file mode 100644 index 00000000..0d567021 --- /dev/null +++ b/.github/workflows/build-docs.yml @@ -0,0 +1,14 @@ +name: Build Production Site + +on: + push: + branches: [release/**/**] + paths: + - '**.md' + +jobs: + dispatch: + runs-on: ubuntu-latest + steps: + - name: Trigger build + run: curl -X POST -d {} "${{ secrets.CLOUDFLARE_BUILD_HOOK }}" \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 92ce26e8..366e3fec 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,12 @@ name: tests workflow on: + pull_request: + paths-ignore: + - "docs/**" + - "samples/**" + - "**.md" + workflow_call: inputs: runtime: diff --git a/.gitignore b/.gitignore index 74e91688..2b76924f 100644 --- a/.gitignore +++ b/.gitignore @@ -173,3 +173,7 @@ fabric.properties # Generated certificates certs/ + +.temp +.cache +node_modules \ No newline at end of file diff --git a/docs/.eslintignore b/docs/.eslintignore new file mode 100644 index 00000000..f4e822b6 --- /dev/null +++ b/docs/.eslintignore @@ -0,0 +1,6 @@ +!.vuepress/ +!.*.js +.cache/ +.temp/ +node_modules/ +dist/ \ No newline at end of file diff --git a/docs/.eslintrc.cjs b/docs/.eslintrc.cjs new file mode 100644 index 00000000..92de49d8 --- /dev/null +++ b/docs/.eslintrc.cjs @@ -0,0 +1,13 @@ +module.exports = { + root: true, + extends: 'vuepress', + overrides: [ + { + files: ['*.ts', '*.vue'], + extends: 'vuepress-typescript', + parserOptions: { + project: ['tsconfig.json'], + }, + }, + ], +} \ No newline at end of file diff --git a/docs/.node-version b/docs/.node-version new file mode 100644 index 00000000..2edeafb0 --- /dev/null +++ b/docs/.node-version @@ -0,0 +1 @@ +20 \ No newline at end of file diff --git a/docs/.vuepress/client.ts b/docs/.vuepress/client.ts new file mode 100644 index 00000000..063caa7a --- /dev/null +++ b/docs/.vuepress/client.ts @@ -0,0 +1,10 @@ +import type {Router} from "vue-router"; + +interface ClientConfig { + enhance?: (context: { + app: any; + router: Router; + siteData: any; + }) => void | Promise; + setup?: () => void; +} \ No newline at end of file diff --git a/docs/.vuepress/config.ts b/docs/.vuepress/config.ts new file mode 100644 index 00000000..b16f12a9 --- /dev/null +++ b/docs/.vuepress/config.ts @@ -0,0 +1,28 @@ +import { dl } from "@mdit/plugin-dl"; +import viteBundler from "@vuepress/bundler-vite"; +import vueDevTools from 'vite-plugin-vue-devtools' +import { defineUserConfig } from "vuepress"; +import { hopeTheme } from "vuepress-theme-hope"; +import { themeOptions } from "./configs/theme"; +import { linkCheckPlugin } from "./markdown/linkCheck"; +import { replaceLinkPlugin } from "./markdown/replaceLink"; + + +export default defineUserConfig({ + base: "/", + dest: "public", + title: "Docs", + description: "Event-native database", + bundler: viteBundler({ viteOptions: { plugins: [vueDevTools(),], } }), + markdown: { importCode: false }, + extendsMarkdown: md => { + md.use(linkCheckPlugin); + md.use(replaceLinkPlugin, { + replaceLink: (link: string, _) => link + .replace("@api", "/api") + .replace("@server/", "/server/{version}/") + }); + md.use(dl); + }, + theme: hopeTheme(themeOptions, { custom: true }), +}); diff --git a/docs/.vuepress/configs/theme.ts b/docs/.vuepress/configs/theme.ts new file mode 100644 index 00000000..41aefcdf --- /dev/null +++ b/docs/.vuepress/configs/theme.ts @@ -0,0 +1,36 @@ +import type {ThemeOptions} from "vuepress-theme-hope"; + +export const themeOptions: ThemeOptions = { + logo: "/Kurrent Logo - Plum.svg", + logoDark: "/Kurrent Logo - White.svg", + docsDir: 'docs', + editLink: false, + lastUpdated: true, + toc: true, + repo: "https://github.com/kurrent-io", + repoLabel: "GitHub", + repoDisplay: true, + contributors: false, + pure: false, + darkmode:"toggle", + headerDepth: 3, + pageInfo: false, + markdown: { + figure: true, + imgLazyload: true, + imgMark: true, + imgSize: true, + tabs: true, + codeTabs: true, + component: true, + mermaid: true, + highlighter: { + type: "shiki", + themes: { + light: "one-light", + dark: "one-dark-pro", + } + } + } +} + diff --git a/docs/.vuepress/lib/externalPlaceholders.ts b/docs/.vuepress/lib/externalPlaceholders.ts new file mode 100644 index 00000000..052bc196 --- /dev/null +++ b/docs/.vuepress/lib/externalPlaceholders.ts @@ -0,0 +1,6 @@ +const externalPlaceholders = ["@samples", "@clients"]; + +export function isKnownPlaceholder(placeholder: string): boolean { + const known = externalPlaceholders.find(x => x == placeholder); + return known !== undefined; +} diff --git a/docs/.vuepress/lib/log.ts b/docs/.vuepress/lib/log.ts new file mode 100644 index 00000000..92b3140b --- /dev/null +++ b/docs/.vuepress/lib/log.ts @@ -0,0 +1,12 @@ +export default { + error(message: string) { + console.log("\x1b[41m%s\x1b[0m", ' ERROR ', `${message}\n`) + process.exit(0) + }, + info(message: string) { + console.log("\x1b[44m%s\x1b[0m", ' INFO ', `${message}\n`) + }, + success(message: string) { + console.log("\x1b[42m\x1b[30m%s\x1b[0m", ' DONE ', `${message}\n`) + } +} diff --git a/docs/.vuepress/lib/types.ts b/docs/.vuepress/lib/types.ts new file mode 100644 index 00000000..35205407 --- /dev/null +++ b/docs/.vuepress/lib/types.ts @@ -0,0 +1,18 @@ +import type {NavItemOptions, SidebarLinkOptions} from "vuepress-theme-hope"; + +export interface EsSidebarGroupOptions extends NavItemOptions { + group?: string; + collapsible?: boolean; + title?: string; + version?: string; + prefix?: string; + link?: string; + children: EsSidebarItemOptions[] | string[]; +} + +export type EsSidebarItemOptions = SidebarLinkOptions | EsSidebarGroupOptions | string; +export type EsSidebarArrayOptions = EsSidebarItemOptions[]; +export type EsSidebarObjectOptions = Record; +export type EsSidebarOptions = EsSidebarArrayOptions | EsSidebarObjectOptions; + +export type ImportedSidebarArrayOptions = EsSidebarGroupOptions[]; \ No newline at end of file diff --git a/docs/.vuepress/lib/version.ts b/docs/.vuepress/lib/version.ts new file mode 100644 index 00000000..92fcbf59 --- /dev/null +++ b/docs/.vuepress/lib/version.ts @@ -0,0 +1,15 @@ +const versionRegex = /v((\d+\.)?(\d+\.)?(\*|\d+))/; +const nightly = "nightly"; +const v = { + isVersion: (v: string) => versionRegex.test(v), + parseVersion: (v: string) => versionRegex.exec(v), + getVersion: (path: string): string | undefined => { + if (path.includes(nightly)) { + return nightly; + } + const ref = path.split("#")[0]; + const split = ref.split("/"); + return split.find(x => v.isVersion(x)); + } +}; +export default v; diff --git a/docs/.vuepress/lib/versioning.ts b/docs/.vuepress/lib/versioning.ts new file mode 100644 index 00000000..ea5eb033 --- /dev/null +++ b/docs/.vuepress/lib/versioning.ts @@ -0,0 +1,135 @@ +import * as fs from "fs"; +import {path} from 'vuepress/utils'; +import log from "./log"; +import {createRequire} from 'node:module'; +// import references from "../versions.json"; +import type { + EsSidebarGroupOptions, EsSidebarObjectOptions, + ImportedSidebarArrayOptions +} from "./types"; + +interface VersionDetail { + version: string, + path: string, + startPage: string +} + +interface Version { + id: string, + group: string, + basePath: string, + versions: VersionDetail[] +} + +const createSidebarItem = (item: EsSidebarGroupOptions, path: string, version: string, group: string): EsSidebarGroupOptions => { + const xp = `/${path}/`; + let ch = item.children as string[]; + if (item.collapsible !== undefined) { + ch = ch.map(x => !x.startsWith('../') ? '../' + x : x); + } + const childPath = item.prefix ? `/${path}${item.prefix}` : xp; + const children = ch.map(x => x.split(xp).join("")); + return { + ...item, + children: children.map(x => `${childPath}${x}`), + prefix: undefined, + group, + version, + text: item.text || item.title || "" + } +} + +export class versioning { + versions: Version[] = []; + + constructor() { + // const require = createRequire(import.meta.url) + // references.forEach(p => { + // const fileName = path.resolve(__dirname, p); + // if (fs.existsSync(fileName)) { + // log.info(`Importing versions from ${fileName}`); + // const list: Version[] = require(fileName); + // list.forEach(v => { + // const existing = this.versions.find(x => x.id === v.id); + // if (existing === undefined) { + // this.versions.push(v); + // } else { + // existing.versions.push(...v.versions); + // } + // }); + // } else { + // log.info(`File ${fileName} doesn't exist, ignoring`); + // } + // }); + } + + get latestSemver(): string { + const serverDocs = this.versions.find(v => v.id === "server"); + if (!serverDocs) { + throw new Error("Server docs not found"); + } + return serverDocs.versions[0].path; + } + + // latest stable release + get latest(): string { + const serverDocs = this.versions.find(v => v.id === "server"); + if (!serverDocs) { + throw new Error("Server docs not found"); + } + return `${serverDocs.basePath}/${serverDocs.versions[0].path}`; + } + + get all() { + return this.versions + } + + // Generate a single object that represents all versions from each sidebar + getSidebars() { + let sidebars: EsSidebarObjectOptions = {}; + const require = createRequire(import.meta.url); + + this.versions.forEach(version => { + version.versions.forEach(v => { + const p = `${version.basePath}/${v.path}`; + const sidebarPath = path.resolve(__dirname, `../../${p}`); + const sidebarBase = path.join(sidebarPath, "sidebar"); + const sidebarJs = `${sidebarBase}.js`; + const sidebarCjs = `${sidebarBase}.cjs`; + fs.copyFileSync(sidebarJs, sidebarCjs); + log.info(`Importing sidebar from ${sidebarJs}`); + const sidebar: ImportedSidebarArrayOptions = require(sidebarCjs); + sidebars[`/${p}/`] = sidebar.map(item => createSidebarItem(item, p, v.version, version.group)); + fs.rmSync(sidebarCjs); + }); + }) + + console.log(JSON.stringify(sidebars, null, 2)); + return sidebars; + } + + version(id: string) { + const ret = this.versions.find(x => x.id === id); + if (ret === undefined) log.error(`Version ${id} not defined`); + return ret; + } + + // Build dropdown items for each version + linksFor(id: string, url?: string) { + const links: { text: string, link: string }[] = []; + const version = this.version(id); + if (version === undefined) return links; + + version.versions.forEach(v => { + const path = `${version.basePath}/${v.path}`; + const pageUrl = (url ? url : v.startPage ? v.startPage : ""); + const link = `/${path}/${pageUrl}`; + const item = {text: v.version, link: link}; + links.push(item); + }); + + return links; + } +} + +export const instance: versioning = new versioning(); diff --git a/docs/.vuepress/markdown/linkCheck/index.ts b/docs/.vuepress/markdown/linkCheck/index.ts new file mode 100644 index 00000000..e6233b64 --- /dev/null +++ b/docs/.vuepress/markdown/linkCheck/index.ts @@ -0,0 +1,90 @@ +import {type PluginSimple} from "markdown-it"; +import {fs, logger, path} from "vuepress/utils"; +import type {MarkdownEnv, MdToken} from "../types"; + +function findAnchor(filename: string, anchor: string): boolean { + const asAnchor = (header: string) => header + .replace(/[^\w\s\-']/gi, "") + .trim() + .toLowerCase() + // @ts-ignore + .replaceAll(" ", "-") + .replaceAll("'", "-"); + + // const enableLogs = filename.endsWith("v24.6/operations.md"); + + const href = ``; + const lines = fs.readFileSync(filename).toString().split("\n"); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (line.includes(href)) return true; + + if (line.charAt(0) != "#") continue; + + const lineAnchor = asAnchor(line); + // if (enableLogs) logger.tip(lineAnchor) + if (lineAnchor === anchor || lineAnchor.replace("--", "-") === anchor) return true; + } + return false; +} + +function checkLink(token: MdToken, attrName: string, env: MarkdownEnv) { + const href = token.attrGet(attrName); + if (href === null) return; + if (href.startsWith("http") || href.endsWith(".html")) return; + ensureLocalLink(href, env, true); +} + +export function ensureLocalLink(href: string, env: MarkdownEnv, ignorePlaceholders: boolean) { + if (ignorePlaceholders && (href.startsWith("@") || env.filePathRelative!.startsWith("samples"))) return; + // check the link + const split = href.split("#"); + const currentPath = href[0] == "/" ? path.resolve(__dirname, "../../..") : path.dirname(env.filePath!); + const p = path.join(currentPath, split[0]); + fs.stat(p, (err, stat) => { + if (err != null) { + logger.error(`Broken link in ${env.filePathRelative}\r\nto: ${split[0]}`); + return; + } + let pathToCheck = p; + if (stat.isDirectory()) { + if (split[0] !== "") { + logger.error(`Link to directory in ${env.filePathRelative}\r\nto: ${href}`); + return; + } + pathToCheck = env.filePath!; + } + if (split.length > 1) { + const anchorResolved = findAnchor(pathToCheck, split[1]); + if (!anchorResolved) { + logger.error(`Broken anchor link in ${env.filePathRelative}: ${split[1]} in file ${pathToCheck}`); + } + } + }); +} + +export const linkCheckPlugin: PluginSimple = (md) => { + md.core.ruler.after( + "inline", + "link-check", + (state) => { + state.tokens.forEach((blockToken) => { + if (!(blockToken.type === "inline" && blockToken.children)) { + return; + } + + blockToken.children.forEach((token) => { + const type = token.type; + switch (type) { + case "link_open": + checkLink(token, "href", state.env); + break; + case "image": + checkLink(token, "src", state.env) + break; + } + }) + }) + } + ) +} diff --git a/docs/.vuepress/markdown/replaceLink/index.ts b/docs/.vuepress/markdown/replaceLink/index.ts new file mode 100644 index 00000000..7bc0e856 --- /dev/null +++ b/docs/.vuepress/markdown/replaceLink/index.ts @@ -0,0 +1,47 @@ +import {type PluginWithOptions} from "markdown-it"; +import {logger} from "vuepress/utils"; +import {isKnownPlaceholder} from "../../lib/externalPlaceholders"; +import type {MarkdownEnv, MdToken} from "../types"; + +export interface ReplaceLinkPluginOptions { + replaceLink?: (link: string, env: any) => string; +} + +function replaceCrossLinks(token: MdToken, env: MarkdownEnv) { + const href = token.attrGet("href"); + if (href === null) return; + if (!href.startsWith("@")) return; + + const placeholder = href.split("/")[0]; + const known = isKnownPlaceholder(placeholder); + + if (!known) { + logger.error(`Unable to resolve placeholder ${placeholder} in ${href}, file ${env.filePathRelative}`); + return; + } +} + +export const replaceLinkPlugin: PluginWithOptions = (md, opts) => { + md.core.ruler.after( + "inline", + "replace-link", + (state) => { + if (opts?.replaceLink === undefined) return; + state.tokens.forEach((blockToken) => { + if (!(blockToken.type === "inline" && blockToken.children)) { + return; + } + + const replaceAttr = (token: MdToken, attrName: string) => token.attrSet(attrName, opts.replaceLink!(token.attrGet(attrName)!, state.env)); + + blockToken.children.forEach((token) => { + const type = token.type; + if (type === "link_open") { + replaceAttr(token, "href"); + replaceCrossLinks(token, state.env); + } + }); + }); + } + ) +} diff --git a/docs/.vuepress/markdown/resolver.ts b/docs/.vuepress/markdown/resolver.ts new file mode 100644 index 00000000..b7078695 --- /dev/null +++ b/docs/.vuepress/markdown/resolver.ts @@ -0,0 +1,30 @@ +import {logger, path} from "vuepress/utils"; +import version from "../lib/version"; +import {instance} from "../lib/versioning"; + +export const resolveVersionedPath = (importPath: string, filePath: string | null | undefined) => { + let importFilePath = importPath; + let error: string | null = null; + + if (!path.isAbsolute(importPath)) { + // if the importPath is a relative path, we need to resolve it + // according to the markdown filePath + if (!filePath) { + logger.error(`Unable to resolve code path: ${filePath}`); + return { + importFilePath: null, + error: 'Error when resolving path', + }; + } + importFilePath = path.resolve(filePath, '..', importPath); + } + + // if (importFilePath.includes("{version}")) { + // const ver = version.getVersion(filePath!) ?? instance.latestSemver; + // if (ver) { + // importFilePath = importFilePath.replace("{version}", ver); + // } + // } + + return {importFilePath, error}; +} \ No newline at end of file diff --git a/docs/.vuepress/markdown/types.ts b/docs/.vuepress/markdown/types.ts new file mode 100644 index 00000000..dfcab225 --- /dev/null +++ b/docs/.vuepress/markdown/types.ts @@ -0,0 +1,40 @@ +import type {PageFrontmatter, PageHeader} from "vuepress"; + +export type MarkdownHeader = PageHeader; + +export interface MarkdownLink { + raw: string; + relative: string; + absolute: string; +} + +export interface MarkdownEnv { + base?: string; + filePath?: string | null; + filePathRelative?: string | null; + frontmatter?: PageFrontmatter; + headers?: MarkdownHeader[]; + hoistedTags?: string[]; + importedFiles?: string[]; + links?: MarkdownLink[]; + title?: string; +} + +type Nesting = 1 | 0 | -1; + +export interface MdToken { + type: string; + tag: string; + attrs: Array<[string, string]> | null; + map: [number, number] | null; + nesting: Nesting; + level: number; + attrSet(name: string, value: string): void; + attrGet(name: string): string | null; +} + +export interface MdEnv { + base: string; + filePath: string; + filePathRelative: string; +} diff --git a/docs/.vuepress/markdown/xode/createImportCodeBlockRule.ts b/docs/.vuepress/markdown/xode/createImportCodeBlockRule.ts new file mode 100644 index 00000000..69fdaf01 --- /dev/null +++ b/docs/.vuepress/markdown/xode/createImportCodeBlockRule.ts @@ -0,0 +1,106 @@ +import {path} from "vuepress/utils" +import type {ExtendedCodeImportPluginOptions, ImportCodeTokenMeta, ResolvedImport} from "./types"; +// @ts-ignore +import type {RuleBlock} from "markdown-it/lib/parser_block"; +// @ts-ignore +import type {StateBlock} from "markdown-it"; + +// min length of the import code syntax, i.e. '@[code]()' +const MIN_LENGTH = 9; + +const startSequence = "@[code"; + +const knownPrismIssues: Record = { + "rs": "rust" +}; + +const replaceKnownPrismExtensions = (ext: string): string => knownPrismIssues[ext] ?? ext; + +// regexp to match the import syntax +const SYNTAX_RE = /^@\[code(?:{(\d+)?-(\d+)?})?(?:{(.+)?})?(?: ([^\]]+))?]\(([^)]*)\)/; + +const name = "tabs"; + +export const createImportCodeBlockRule = ({ + handleImportPath = (str) => [{importPath: str}], + }: ExtendedCodeImportPluginOptions): RuleBlock => ( + state: StateBlock, + startLine: number, + endLine: number, + silent: boolean +): boolean => { + // if it's indented more than 3 spaces, it should be a code block + /* istanbul ignore if */ + if (state.sCount[startLine] - state.blkIndent >= 4) { + return false; + } + + const pos = state.bMarks[startLine] + state.tShift[startLine]; + const max = state.eMarks[startLine]; + + // return false if the length is shorter than min length + if (pos + MIN_LENGTH > max) return false; + + // check if it's matched the start + if (state.src.substr(pos, startSequence.length) !== startSequence) return false; + + // check if it's matched the syntax + const match = state.src.slice(pos, max).match(SYNTAX_RE); + if (!match) return false; + + // return true as we have matched the syntax + if (silent) return true; + + const [, lineStart, lineEnd, region, info, importPath] = match; + + const resolvedImports = handleImportPath(importPath); + + const addCodeBlock = (r: ResolvedImport) => { + const meta: ImportCodeTokenMeta = { + importPath: r.importPath, + lineStart: lineStart ? Number.parseInt(lineStart, 10) : 0, + lineEnd: lineEnd ? Number.parseInt(lineEnd, 10) : undefined, + region: region + }; + + // create an import_code token + const token = state.push('import_code', 'code', 0); + + // use user specified info, or fallback to file ext + token.info = info ?? replaceKnownPrismExtensions(path.extname(meta.importPath).slice(1)); + token.markup = '```'; + token.map = [startLine, startLine + 1]; + // store token meta to be used in renderer rule + token.meta = meta; + } + + const addGroupItem = (r: ResolvedImport) => { + const token = state.push(`${name}_tab_open`, "", 1); + token.block = true; + token.info = r.label; + token.meta = {active: false}; + + addCodeBlock(r); + + state.push(`${name}_tab_close`, "", -1); + } + + const experiment = resolvedImports.length > 1; + if (experiment) { + const token = state.push(`${name}_tabs_open`, "", 1); + token.info = name; + token.meta = {id: "code"}; + + for (const resolved of resolvedImports) { + addGroupItem(resolved); + } + + state.push(`${name}_tabs_close`, "", -1); + } else { + addCodeBlock(resolvedImports[0]); + } + + state.line = startLine + 1; + + return true; +} diff --git a/docs/.vuepress/markdown/xode/importCodePlugin.ts b/docs/.vuepress/markdown/xode/importCodePlugin.ts new file mode 100644 index 00000000..d3bf50de --- /dev/null +++ b/docs/.vuepress/markdown/xode/importCodePlugin.ts @@ -0,0 +1,45 @@ +import type {PluginWithOptions} from "markdown-it"; +import type {MarkdownEnv} from "../types"; +import {resolveImportCode} from "./resolveImportCode"; +import {createImportCodeBlockRule} from "./createImportCodeBlockRule"; +import {type ExtendedCodeImportPluginOptions} from "./types"; +import { normalizeWhitespace } from "./normalizeWhitespace"; + +export const importCodePlugin: PluginWithOptions = ( + md, + options = {} +): void => { + // add import_code block rule + md.block.ruler.before( + 'fence', + 'import_code', + createImportCodeBlockRule(options), + { + alt: ['paragraph', 'reference', 'blockquote', 'list'], + } + ); + + // add import_code renderer rule + md.renderer.rules.import_code = ( + tokens, + idx, + options, + env: MarkdownEnv, + slf + ) => { + const token = tokens[idx]; + + // use imported code as token content + const {importFilePath, importCode} = resolveImportCode(token.meta, env); + token.content = normalizeWhitespace(importCode); + + // extract imported files to env + if (importFilePath) { + const importedFiles = env.importedFiles || (env.importedFiles = []); + importedFiles.push(importFilePath); + } + + // render the import_code token as a fence token + return md.renderer.rules.fence!(tokens, idx, options, env, slf); + } +} diff --git a/docs/.vuepress/markdown/xode/normalizeWhitespace.ts b/docs/.vuepress/markdown/xode/normalizeWhitespace.ts new file mode 100644 index 00000000..a4127f6a --- /dev/null +++ b/docs/.vuepress/markdown/xode/normalizeWhitespace.ts @@ -0,0 +1,14 @@ +export const normalizeWhitespace = (input: string): string => { + // empty lines before start of snippet + const trimmed = input.replace(/^([ ]*\n)*/, ''); + + // find the shortest indent at the start of line + const shortest = trimmed.match(/^[ ]*(?=\S)/gm)?.reduce((a, b) => a.length <= b.length ? a : b) ?? ''; + + if (shortest.length) { + // remove the shortest indent from each line (if exists) + return trimmed.replace(new RegExp(`^${shortest}`, 'gm'), ''); + } + + return trimmed; +} diff --git a/docs/.vuepress/markdown/xode/resolveImportCode.ts b/docs/.vuepress/markdown/xode/resolveImportCode.ts new file mode 100644 index 00000000..93b8f565 --- /dev/null +++ b/docs/.vuepress/markdown/xode/resolveImportCode.ts @@ -0,0 +1,92 @@ +import {fs} from "vuepress/utils"; +import type {MarkdownEnv} from "../types"; +import type {ImportCodeTokenMeta} from "./types"; +import {resolveVersionedPath} from "../resolver"; + +function testLine(line: string, regexp: RegExp, regionName: string, end = false) { + const [full, tag, name] = regexp.exec(line.trim()) || []; + return ( + full + && tag + && name === regionName + && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/) + ); +} + +function findRegion(lines: string[] | null, regionName: string) { + if (lines === null) return undefined; + const regionRegexps = [ + /^\/\/ ?#?((?:end)?region) ([\w*-]+)$/, // javascript, typescript, java, go + /^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/, // css, less, scss + /^#pragma ((?:end)?region) ([\w*-]+)$/, // C, C++ + /^$/, // HTML, markdown + /^#(End Region) ([\w*-]+)$/, // Visual Basic + /^::#(endregion) ([\w*-]+)$/, // Bat + /^# ?((?:end)?region) ([\w*-]+)$/ // C#, PHP, PowerShell, Python, perl & misc + ]; + + let regexp = null; + let start = -1; + + for (const [lineId, line] of lines.entries()) { + if (regexp === null) { + for (const reg of regionRegexps) { + if (testLine(line, reg, regionName)) { + start = lineId + 1; + regexp = reg; + break; + } + } + } else if (testLine(line, regexp, regionName, true)) { + return {start, end: lineId, regexp}; + } + } + + return null; +} + +export const resolveImportCode = ( + {importPath, lineStart, lineEnd, region}: ImportCodeTokenMeta, + {filePath}: MarkdownEnv +): { + importFilePath: string | null + importCode: string +} => { + const {importFilePath, error} = resolveVersionedPath(importPath, filePath); + if (importFilePath === null || error !== null){ + return {importFilePath, importCode: error!}; + } + + // read file content + const fileContent = fs.readFileSync(importFilePath).toString(); + + const removeSpaces = (l: string[]) => { + if (l.length === 0) return l; + const spaces = l[0].length - l[0].trimStart().length; + if (spaces === 0) return l; + return l.map(v => v.substr(spaces)); + } + + const allLines = (fileContent != null) ? fileContent.split('\n') : null; + if (!allLines) return {importFilePath, importCode: "Code is empty"}; + if (region) { + const reg = findRegion(allLines, region); + if (reg) { + lineStart = reg.start + 1; + lineEnd = reg.end; + } + } + + const lines = allLines + .slice(lineStart ? lineStart - 1 : lineStart, lineEnd) + .map(x => x.replace(/\t/g, " ")); + const code = removeSpaces(lines) + .join('\n') + .replace(/\n?$/, '\n'); + + // resolve partial import + return { + importFilePath, + importCode: code, + }; +} diff --git a/docs/.vuepress/markdown/xode/types.ts b/docs/.vuepress/markdown/xode/types.ts new file mode 100644 index 00000000..f3a34d62 --- /dev/null +++ b/docs/.vuepress/markdown/xode/types.ts @@ -0,0 +1,15 @@ +export interface ImportCodeTokenMeta { + importPath: string; + lineStart: number; + lineEnd?: number; + region?: string; +} + +export interface ResolvedImport { + label?: string; + importPath: string; +} + +export interface ExtendedCodeImportPluginOptions { + handleImportPath?: (files: string) => ResolvedImport[]; +} diff --git a/docs/.vuepress/public/Kurrent Logo - Black.svg b/docs/.vuepress/public/Kurrent Logo - Black.svg new file mode 100644 index 00000000..6e2ea3bb --- /dev/null +++ b/docs/.vuepress/public/Kurrent Logo - Black.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/.vuepress/public/Kurrent Logo - Plum.svg b/docs/.vuepress/public/Kurrent Logo - Plum.svg new file mode 100644 index 00000000..ea6f8696 --- /dev/null +++ b/docs/.vuepress/public/Kurrent Logo - Plum.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/.vuepress/public/Kurrent Logo - White.svg b/docs/.vuepress/public/Kurrent Logo - White.svg new file mode 100644 index 00000000..739a8cea --- /dev/null +++ b/docs/.vuepress/public/Kurrent Logo - White.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/.vuepress/public/cloud.png b/docs/.vuepress/public/cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..c9c61b8f5bf1fbcf369473db2006424ba6eae5c4 GIT binary patch literal 247451 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

Fp&B+>MSu|fWLNJGM%Ob#)m9!1fn-lf6damKEV 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

p;j-aF1zH6vsc>Zs`I9Z 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 literal 0 HcmV?d00001 diff --git a/docs/.vuepress/public/fonts/Solina-Regular.woff b/docs/.vuepress/public/fonts/Solina-Regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..2753ec2fd2d66b96ab13614158be584d454ca288 GIT binary patch literal 17800 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 literal 0 HcmV?d00001 diff --git a/docs/.vuepress/public/fonts/Solina-Regular.woff2 b/docs/.vuepress/public/fonts/Solina-Regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..29565392eedd536882ca26a9432b3bb7d3a0ccdd GIT binary patch literal 16312 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

L5}!wbyJzinby~Y}wl*>_uq3k6=ZVq4m$0sq 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 -1) { + var c = document.querySelector("link[rel='canonical']"); + args.push({ + __t: "bpc", + c: c && c.getAttribute("href") || undefined, + p: location.pathname, + u: location.href, + s: location.search, + t: document.title, + r: document.referrer + }); + } + + args.unshift(e); + analytics.push(args); + return analytics; + }; + }; + + for (var i = 0; i < analytics.methods.length; i++) { + var key = analytics.methods[i]; + analytics[key] = analytics.factory(key); + } + + analytics.load = function (key, options) { + var t = document.createElement("script"); + t.type = "text/javascript"; + t.async = true; + t.setAttribute("data-global-segment-analytics-key", globalAnalyticsKey) + t.src = "https://cloud.kurrent.io/segment/ajs/REDACTED"; + + var first = document.getElementsByTagName("script")[0]; + first.parentNode.insertBefore(t, first); + analytics._loadOptions = options; + }; + analytics._writeKey = "REDACTED"; + analytics.SNIPPET_VERSION = "5.2.1"; + analytics.load("REDACTED"); +})(); diff --git a/docs/.vuepress/public/logo-white.png b/docs/.vuepress/public/logo-white.png new file mode 100644 index 0000000000000000000000000000000000000000..107eb88ce759d9aaf307148b7dcc4bed9423269c GIT binary patch literal 15352 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 literal 0 HcmV?d00001 diff --git a/docs/.vuepress/public/robots.txt b/docs/.vuepress/public/robots.txt new file mode 100644 index 00000000..dbe84f0a --- /dev/null +++ b/docs/.vuepress/public/robots.txt @@ -0,0 +1,15 @@ +User-agent: * + +Disallow: /.algolia/ +Disallow: /.github/ +Disallow: /.vscode/ +Disallow: /import/ +Disallow: /.gitattributes +Disallow: /.gitignore +Disallow: /.node-version +Disallow: /codeql-analysis.yml +Disallow: /package.json +Disallow: /serve.js +Disallow: /yarn.lock + +Sitemap: https://docs.kurrent.io/sitemap.xml diff --git a/docs/.vuepress/public/video.png b/docs/.vuepress/public/video.png new file mode 100644 index 0000000000000000000000000000000000000000..b6fcd2c1d9fc2a3858892cd7213adcf2bc90445e GIT binary patch literal 8640 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 p, +.theme-hope-content:not(.custom) > ol p, +.theme-hope-content:not(.custom) > ul p { + text-align: left; +} + +html[data-theme="dark"] #kapa-widget-portal { + code { + background: rgba(127, 127, 127, 0.12); + } + + blockquote { + border-color: #eee; + } +} + +/* Fix for center-alignment issue on `.not-found` pages */ +.vp-page.not-found .theme-hope-content, +.vp-page.not-found .vp-breadcrumb, +.vp-page.not-found .vp-page-title, +.vp-page.not-found .vp-toc-placeholder { + text-align: initial; + width: var(--content-width, 740px); +} + +.vp-hero-info { + text-align: center; +} + +.DocSearch-Button-Keys { + display: none; +} + +.DocSearch-Button-Placeholder { + padding-right: 30px; +} + +#main-description { + max-width: 50rem; +} + +.vp-highlight-header { + text-align: center; +} + +.vp-highlight-info-wrapper:only-child { + flex: 1; +} + +/*Remove deprecation notice*/ +div[style*="z-index: 2147483647"] { + display: none !important; + visibility: hidden !important; + opacity: 0 !important; + position: absolute !important; + pointer-events: none !important; +} + +.vp-hero-title { + margin: 0.5rem 0; + background: linear-gradient( 120deg, var(--vp-c-accent-hover), var(--vp-c-accent) 30%, var(--end-gradient) 120% ); + -webkit-background-clip: text; + background-clip: text; + font-weight: bold; + font-size: 3.6rem; + font-family: var(--vp-font); + line-height: 1.5; + -webkit-text-fill-color: transparent; +} + +.vp-highlight-item { + list-style: none; +} + +@media screen and (max-width: 480px) { + .vp-action, + .custom-class-kapa, + .kapa-container { + display: none; + } +} + +.vp-highlight-title { + font-size: 1.4rem; +} diff --git a/docs/.vuepress/styles/palette.scss b/docs/.vuepress/styles/palette.scss new file mode 100644 index 00000000..f87d0920 --- /dev/null +++ b/docs/.vuepress/styles/palette.scss @@ -0,0 +1,193 @@ +@use 'sass:color'; + +/* Primary colors */ +$main-color: #631b3a; +$secondary-color: #B75781; + +/* Light Theme Colors */ +$color-background-light: #ffffff; +$color-foreground-light: #000000; +$color-link-light: #479bff; +$color-title-light: $main-color; + +/* Dark Theme Colors */ +$color-background-dark: #080b0d; +$color-foreground-dark: #f0f0f0; +$color-title-dark: #f0f0f0; + +$theme-color-light: color.mix(black, $main-color, 10%); // Darken by 10% +$theme-color-soft: #{color.scale(#631b3a, $lightness: 85%)}; +$theme-color-dark: color.mix(white, $main-color, 10%); // Lighten by 10% +$theme-color-mask: color.adjust( $secondary-color, $alpha: -0.85 ); // Reduce opacity + +/* CSS Variable Definitions */ +:root { + --main-color: #{$main-color}; + --secondary-color: #{$secondary-color}; + --end-gradient: #{$secondary-color}; + --color-link: #{$color-link-light}; + --theme-name: light; + --theme-shade: light; + --theme-contrast: low; + --color-background: #{$color-background-light}; + --color-foreground: #{$color-foreground-light}; + --color-title: var(--main-color); + --color-title-contrast: #ffffff; + --color-highlight: var(--main-color); + --color-highlight-contrast: #ffffff; + --color-focus: #8d5fff; + --color-focus-contrast: #ffffff; + --color-error: #b75781; + --color-error-contrast: #ffffff; + --color-error-alt: #dbabc0; + --color-error-alt-contrast: #000000; + --color-warning: #7d6f05; + --color-warning-contrast: #ffffff; + --color-warning-alt: #fcf29b; + --color-warning-alt-contrast: #000000; + --color-success: #2c667d; + --color-success-contrast: #ffffff; + --color-success-alt: #dbf9ee; + --color-success-alt-contrast: #000000; + --color-info: #4855a7; + --color-info-contrast: #ffffff; + --color-info-alt: #edf1fc; + --color-info-alt-contrast: #000000; + --color-shade-10: #f5f8f9; + --color-shade-20: #ecf1f3; + --color-shade-30: #e3eaed; + --color-shade-40: #d9e3e8; + --color-shade-50: #d0dce2; + --color-shade-60: #b4c8d1; + --color-overlay: #a79ab8; + --color-overlay-alpha: 0.75; + --color-disabled: #ecf1f3; + --color-disabled-border: #ecf1f3; + --color-disabled-contrast: #000000; + --code-fg: #383a42; + --code-bg: #fffffe; + --code-literal: #0184bc; + --code-symbol: #4078f2; + --code-keyword: #a626a4; + --code-string: #50a14f; + --code-error: #e45649; + --code-variable: #986801; + --code-class: #c18401; + --code-comment: #6f7f90; +} + +/* Dark Theme */ +@media (prefers-color-scheme: dark) { + :root { + --theme-name: dark; + --theme-shade: dark; + --theme-contrast: low; + --end-gradient: #{$main-color}; + --color-background: #{$color-background-dark}; + --color-foreground: #{$color-foreground-dark}; + --theme-name: dark; + --theme-shade: dark; + --theme-contrast: low; + --color-background: #080b0d; + --color-foreground: #f0f0f0; + --color-title: #f0f0f0; + --color-title-contrast: #080b0d; + --color-highlight: #64edbb; + --color-highlight-contrast: #080b0d; + --color-link: #479bff; + --color-link-contrast: #080b0d; + --color-focus: #8d5fff; + --color-focus-contrast: #080b0d; + --color-error: #ff4a80; + --color-error-contrast: #080b0d; + --color-error-alt: #631b3a; + --color-error-alt-contrast: #ffffff; + --color-warning: #ffed4e; + --color-warning-contrast: #080b0d; + --color-warning-alt: #7d6f05; + --color-warning-alt-contrast: #ffffff; + --color-success: #64edbb; + --color-success-contrast: #080b0d; + --color-success-alt: #2c667d; + --color-success-alt-contrast: #ffffff; + --color-info: #479bff; + --color-info-contrast: #080b0d; + --color-info-alt: #4855a7; + --color-info-alt-contrast: #ffffff; + --color-shade-10: #161c1e; + --color-shade-20: #1e2528; + --color-shade-30: #262e31; + --color-shade-40: #2e383b; + --color-shade-50: #364146; + --color-shade-60: #3f4c50; + --color-overlay: #2c667d; + --color-overlay-alpha: 0.75; + --color-disabled: #1e2528; + --color-disabled-border: #1e2528; + --color-disabled-contrast: #f0f0f0; + --code-fg: #d7dae0; + --code-bg: #313440; + --code-literal: #e5c07b; + --code-symbol: #56b6c2; + --code-keyword: #c678dd; + --code-string: #98c379; + --code-error: #e05252; + --code-variable: #e06c75; + --code-class: #e5c07b; + --code-comment: #5c6370; + } +} + +$vp-font: 'Solina, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, "Helvetica Neue", Arial, "Noto Sans", STHeiti, "Microsoft YaHei", SimSun, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"'; +$vp-font-heading: 'Solina, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", STHeiti, "Microsoft YaHei", SimSun, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"'; + +html[data-theme="dark"] { + --theme-color: var(--secondary-color); + --vp-c-accent-hover: var(--secondary-color); + --vp-c-accent: var(--secondary-color); + --vp-c-accent-bg: var(--secondary-color); + --vp-c-accent-soft: var(--main-color); + --theme-color-light: #{$theme-color-light}; + --theme-color-dark: #{$theme-color-dark}; + --theme-color-mask: #{$theme-color-mask}; + --end-gradient: #{$main-color}; +} + +html[data-theme="light"] { + --theme-color: var(--main-color); + --vp-c-accent-hover: var(--main-color); + --vp-c-accent: var(--main-color); + --vp-c-accent-bg: var(--main-color); + --vp-c-accent-soft: #{$theme-color-soft}; + --theme-color-light: #{$theme-color-light}; + --theme-color-dark: #{$theme-color-dark}; + --theme-color-mask: #{$theme-color-mask}; +} + +$vp-c-bg: ( light: #fff, dark: #080b0d, ); + +$vp-c-bg-elv-soft: ( light: #fff, dark: #080b0d, ); + +$font-body: 15px; + +/* Override Code Block Background */ +$sidebar-width: 18rem; + +$vp-c-text: ( light: #000, dark: #f0f0f0, ); + +.hint-container.important a, +.hint-container.info a, +.hint-container.note a, +.hint-container.tip a, +.hint-container.warning a, +.hint-container.caution a { + color: var(--color-link-light); + + html[data-theme="dark"] & { + color: var(--color-link); + } +} + +.vp-feature-item { + flex-basis: 21%; +} diff --git a/docs/api/appending-events.md b/docs/api/appending-events.md new file mode 100644 index 00000000..89846655 --- /dev/null +++ b/docs/api/appending-events.md @@ -0,0 +1,246 @@ +--- +order: 2 +--- + +# Appending events + +When you start working with EventStoreDB, your application streams are empty. The first meaningful operation is to add one or more events to the database using this API. + +::: tip +Check the [Getting Started](getting-started.md) guide to learn how to configure and use the client SDK. +::: + +## Append your first event + +The simplest way to append an event to EventStoreDB is to create an `EventData` object and call `appendToStream` method. + +```java {32-43} +class OrderPlaced { + private String orderId; + private String customerId; + private double totalAmount; + private String status; + + public OrderPlaced(String orderId, String customerId, double totalAmount, String status) { + this.orderId = orderId; + this.customerId = customerId; + this.totalAmount = totalAmount; + this.status = status; + } + + public String getOrderId() { + return orderId; + } + + public String getCustomerId() { + return customerId; + } + + public double getTotalAmount() { + return totalAmount; + } + + public String getStatus() { + return status; + } +} + + +EventData eventData = EventData + .builderAsJson( + UUID.randomUUID(), + "OrderPlaced", + new OrderPlaced("order-456", "customer-789", 249.99, "confirmed")) + .build(); + +AppendToStreamOptions options = AppendToStreamOptions.get() + .expectedRevision(ExpectedRevision.noStream()); + +client.appendToStream("orders", options, eventData) + .get(); + +``` + +`appendToStream` takes a collection or a single object that can be serialized in JSON or binary format, which allows you to save more than one event in a single batch. + +Outside the example above, other options exist for dealing with different scenarios. + +::: tip +If you are new to Event Sourcing, please study the [Handling concurrency](#handling-concurrency) section below. +::: + +## Working with EventData + +Events appended to EventStoreDB must be wrapped in an `EventData` object. This allows you to specify the event's content, the type of event, and whether it's in JSON format. In its simplest form, you need three arguments: **eventId**, **eventType**, and **eventData**. + +### eventId + +This takes the format of a `UUID` and is used to uniquely identify the event you are trying to append. If two events with the same `UUID` are appended to the same stream in quick succession, EventStoreDB will only append one of the events to the stream. + +For example, the following code will only append a single event: + +```java {3,15-16} +EventData eventData = EventData + .builderAsJson( + UUID.randomUUID(), + "OrderPlaced", + new OrderPlaced("order-456", "customer-789", 249.99, "confirmed")) + .build(); + +AppendToStreamOptions options = AppendToStreamOptions.get() + .expectedRevision(ExpectedRevision.any()); + +client.appendToStream("orders", options, eventData) + .get(); + +// attempt to append the same event again +client.appendToStream("orders", options, eventData) + .get(); +``` + +### eventType + +Each event should be supplied with an event type. This unique string is used to identify the type of event you are saving. + +It is common to see the explicit event code type name used as the type as it makes serialising and de-serialising of the event easy. However, we recommend against this as it couples the storage to the type and will make it more difficult if you need to version the event at a later date. + +### eventData + +Representation of your event data. It is recommended that you store your events as JSON objects. This allows you to take advantage of all of EventStoreDB's functionality, such as projections. That said, you can save events using whatever format suits your workflow. Eventually, the data will be stored as encoded bytes. + +### userMetadata + +Storing additional information alongside your event that is part of the event itself is standard practice. This can be correlation IDs, timestamps, access information, etc. EventStoreDB allows you to store a separate byte array containing this information to keep it separate. + +### contentType + +The content type indicates whether the event is stored as JSON or binary format. This is automatically set when using the builder methods like `builderAsJson()` or `builderAsBinary()`. + +## Handling concurrency + +When appending events to a stream, you can supply an *expected revision*. Your client uses this to inform EventStoreDB of the state or version you expect the stream to be in when appending an event. If the stream isn't in that state, an exception will be thrown. + +For example, if you try to append the same record twice, expecting both times that the stream doesn't exist, you will get an exception on the second: + +```java +EventData eventDataOne = EventData + .builderAsJson( + UUID.randomUUID(), + "OrderPlaced", + new OrderPlaced("order-456", "customer-789", 249.99, "confirmed")) + .build(); + +EventData eventDataTwo = EventData + .builderAsJson( + UUID.randomUUID(), + "OrderPlaced", + new OrderPlaced("order-457", "customer-789", 249.99, "confirmed")) + .build(); + +AppendToStreamOptions options = AppendToStreamOptions.get() + .expectedRevision(ExpectedRevision.noStream()); + +client.appendToStream("no-stream-stream", options, eventDataOne) + .get(); + +// attempt to append the same event again +client.appendToStream("no-stream-stream", options, eventDataTwo) + .get(); +``` + +There are several available expected revision options: +- `ExpectedRevision.any()` - No concurrency check +- `ExpectedRevision.noStream()` - Stream should not exist +- `ExpectedRevision.streamExists()` - Stream should exist +- `ExpectedRevision.expectedRevision(long revision)` - Stream should be at specific revision + +This check can be used to implement optimistic concurrency. When retrieving a stream from EventStoreDB, note the current version number. When you save it back, you can determine if somebody else has modified the record in the meantime. + +First, let's define the event classes for our ecommerce example: + +```java +public class PaymentProcessed { + private String orderId; + private String paymentId; + private double amount; + private String paymentMethod; + + public PaymentProcessed(String orderId, String paymentId, double amount, String paymentMethod) { + this.orderId = orderId; + this.paymentId = paymentId; + this.amount = amount; + this.paymentMethod = paymentMethod; + } + // getters omitted for brevity +} + +public class OrderCancelled { + private String orderId; + private String reason; + private String comment; + + public OrderCancelled(String orderId, String reason, String comment) { + this.orderId = orderId; + this.reason = reason; + this.comment = comment; + } + // getters omitted for brevity +} +``` + +Now, here's how to implement optimistic concurrency control: + +```java +ReadStreamOptions readOptions = ReadStreamOptions.get() + .forwards() + .fromStart(); + +ReadResult result = client.readStream("order-12345", readOptions) + .get(); + +// Get the current revision to use for optimistic concurrency +long currentRevision = result.getLastStreamPosition(); + +// Two concurrent operations trying to update the same order +EventData paymentProcessedEvent = EventData + .builderAsJson( + UUID.randomUUID(), + "PaymentProcessed", + new PaymentProcessed("order-12345", "payment-789", 149.99, "VISA")) + .build(); + +EventData orderCancelledEvent = EventData + .builderAsJson( + UUID.randomUUID(), + "OrderCancelled", + new OrderCancelled("order-12345", "customer-request", "Customer changed mind")) + .build(); + +// Process payment (succeeds) +AppendToStreamOptions appendOptions = AppendToStreamOptions.get() + .streamRevision(currentRevision); + +WriteResult paymentResult = client.appendToStream("order-12345", appendOptions, paymentProcessedEvent) + .get(); + +// Cancel order (fails due to concurrency conflict) +AppendToStreamOptions cancelOptions = AppendToStreamOptions.get() + .streamRevision(currentRevision); + +client.appendToStream("order-12345", cancelOptions, orderCancelledEvent) + .get(); +``` + +## User credentials + +You can provide user credentials to append the data as follows. This will override the default credentials set on the connection. + +```java +UserCredentials credentials = new UserCredentials("admin", "changeit"); + +AppendToStreamOptions options = AppendToStreamOptions.get() + .authenticated(credentials); + +client.appendToStream("some-stream", options, eventData) + .get(); +``` \ No newline at end of file diff --git a/docs/api/authentication.md b/docs/api/authentication.md new file mode 100644 index 00000000..521cebbc --- /dev/null +++ b/docs/api/authentication.md @@ -0,0 +1,43 @@ +--- +title: Authentication +order: 7 +head: + - - title + - {} + - Authentication | Java | Clients | EventStore Docs +--- + +# Client x.509 certificate + + + +X.509 certificates are digital certificates that use the X.509 public key infrastructure (PKI) standard to verify the identity of clients and servers. They play a crucial role in establishing a secure connection by providing a way to authenticate identities and establish trust. + +## Prerequisites + +1. KurrentDB 25.0 or greater, or EventStoreDB 24.10 or later. +2. A valid X.509 certificate configured on the Database. See [configuration steps](@server/security/user-authentication.html#user-x-509-certificates) for more details. + +## Connect using an x.509 certificate + +To connect using an x.509 certificate, you need to provide the certificate and +the private key to the client. If both username or password and certificate +authentication data are supplied, the client prioritizes user credentials for +authentication. The client will throw an error if the certificate and the key +are not both provided. + +The client supports the following parameters: + +| Parameter | Description | +|----------------|--------------------------------------------------------------------------------| +| `userCertFile` | The file containing the X.509 user certificate in PEM format. | +| `userKeyFile` | The file containing the user certificate’s matching private key in PEM format. | + +To authenticate, include these two parameters in your connection string or constructor when initializing the client: + +```java +EventStoreDBClientSettings settings = EventStoreDBConnectionString + .parseOrThrow("esdb://admin:changeit@{endpoint}?tls=true&userCertFile={pathToCaFile}&userKeyFile={pathToKeyFile}"); + +EventStoreDBClient client = EventStoreDBClient.create(settings); +``` \ No newline at end of file diff --git a/docs/api/delete-stream.md b/docs/api/delete-stream.md new file mode 100644 index 00000000..262c70af --- /dev/null +++ b/docs/api/delete-stream.md @@ -0,0 +1,48 @@ +--- +order: 9 +head: + - - title + - {} + - Deleting Events | Java | Clients | EventStore Docs +--- + +# Deleting Events + +In EventStoreDB, you can delete events and streams either partially or +completely. Settings like $maxAge and $maxCount help control how long events are +kept or how many events are stored in a stream, but they won't delete the entire +stream. When you need to fully remove a stream, EventStoreDB offers two +options: Soft Delete and Hard Delete. + +## Soft delete + +Soft delete in EventStoreDB allows you to mark a stream for deletion without +completely removing it, so you can still add new events later. While you can do +this through the UI, using code is often better for automating the process, +handling many streams at once, or including custom rules. Code is especially +helpful for large-scale deletions or when you need to integrate soft deletes +into other workflows. + +```java +client.deleteStream(streamName, DeleteStreamOptions.get()).get(); +``` + +::: note +Clicking the delete button in the UI performs a soft delete, setting the +TruncateBefore value to remove all events up to a certain point. While this +marks the events for deletion, actual removal occurs during the next scavenging +process. The stream can still be reopened by appending new events. +::: + +## Hard delete + +Hard delete in EventStoreDB permanently removes a stream and its events. While +you can use the HTTP API, code is often better for automating the process, +managing multiple streams, and ensuring precise control. Code is especially +useful when you need to integrate hard delete into larger workflows or apply +specific conditions. Note that when a stream is hard deleted, you cannot reuse +the stream name, it will raise an exception if you try to append to it again. + +```java +client.tombstoneStream(streamName, DeleteStreamOptions.get()).get(); +``` \ No newline at end of file diff --git a/docs/api/getting-started.md b/docs/api/getting-started.md new file mode 100644 index 00000000..a6e5771a --- /dev/null +++ b/docs/api/getting-started.md @@ -0,0 +1,221 @@ +--- +order: 1 +head: + - - title + - {} + - Getting Started | Java | Clients | EventStoreDB Docs +--- + +# Getting started + +This guide will help you get started with EventStoreDB in your Java application. +It covers the basic steps to connect to EventStoreDB, create events, append them +to streams, and read them back. + +## Required packages + +Add the `db-client-java` dependency to your project: + +::: tabs +@tab gradle +```bash +implementation 'com.eventstore:db-client-java:5.4.x' +``` +@tab maven +```bash + + com.eventstore + db-client-java + 5.4.x + +``` +::: + +## Connecting to EventStoreDB + +To connect your application to EventStoreDB, you need to configure and create a client instance. + +::: tip Insecure clusters +The recommended way to connect to EventStoreDB is using secure mode (which is +the default). However, if your EventStoreDB instance is running in insecure +mode, you must explicitly set `tls=false` in your [connection +string](#connection-string) or client configuration. +::: + +EventStoreDB uses connection strings to configure the client connection. The connection string supports two protocols: + +- **`esdb://`** - for connecting directly to specific node endpoints (single node or multi-node cluster with explicit endpoints) +- **`esdb+discover://`** - for connecting using cluster discovery via DNS or gossip endpoints + +When using `esdb://`, you specify the exact endpoints to connect to. The client will connect directly to these endpoints. For multi-node clusters, you can specify multiple endpoints separated by commas, and the client will query each node's Gossip API to get cluster information, then picks a node based on the URI's node preference. + +With `esdb+discover://`, the client uses cluster discovery to find available nodes. This is particularly useful when you have a DNS A record pointing to cluster nodes or when you want the client to automatically discover the cluster topology. + +::: info Gossip support +Since version 22.10, EventStoreDB supports gossip on single-node deployments, so +`esdb+discover://` can be used for any topology, including single-node setups. +::: + +For cluster connections using discovery, use the following format: + +``` +esdb+discover://admin:changeit@cluster.dns.name:2113 +``` + +Where `cluster.dns.name` is a DNS `A` record that points to all cluster nodes. + +For direct connections to specific endpoints, you can specify individual nodes: + +``` +esdb://admin:changeit@node1.dns.name:2113,node2.dns.name:2113,node3.dns.name:2113 +``` + +Or for a single node: + +``` +esdb://admin:changeit@localhost:2113 +``` + +There are a number of query parameters that can be used in the connection string to instruct the cluster how and where the connection should be established. All query parameters are optional. + +| Parameter | Accepted values | Default | Description | +|-----------------------|---------------------------------------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------| +| `tls` | `true`, `false` | `true` | Use secure connection, set to `false` when connecting to a non-secure server or cluster. | +| `connectionName` | Any string | None | Connection name | +| `maxDiscoverAttempts` | Number | `10` | Number of attempts to discover the cluster. | +| `discoveryInterval` | Number | `100` | Cluster discovery polling interval in milliseconds. | +| `gossipTimeout` | Number | `5` | Gossip timeout in seconds, when the gossip call times out, it will be retried. | +| `nodePreference` | `leader`, `follower`, `random`, `readOnlyReplica` | `leader` | Preferred node role. When creating a client for write operations, always use `leader`. | +| `tlsVerifyCert` | `true`, `false` | `true` | In secure mode, set to `true` when using an untrusted connection to the node if you don't have the CA file available. Don't use in production. | +| `tlsCaFile` | String, file path | None | Path to the CA file when connecting to a secure cluster with a certificate that's not signed by a trusted CA. | +| `defaultDeadline` | Number | None | Default timeout for client operations, in milliseconds. Most clients allow overriding the deadline per operation. | +| `keepAliveInterval` | Number | `10` | Interval between keep-alive ping calls, in seconds. | +| `keepAliveTimeout` | Number | `10` | Keep-alive ping call timeout, in seconds. | +| `userCertFile` | String, file path | None | User certificate file for X.509 authentication. | +| `userKeyFile` | String, file path | None | Key file for the user certificate used for X.509 authentication. | +| `dnsDiscover` | `true`, `false` | `false` | Enable DNS-based cluster discovery. When `true`, resolves hostnames to discover cluster nodes. Use with `feature=dns-lookup` for full DNS resolution. | +| `feature` | `dns-lookup` | None | Enable specific client features. Use `dns-lookup` with `dnsDiscover=true` to resolve hostnames to multiple IP addresses for cluster discovery. | + +When connecting to an insecure instance, specify `tls=false` parameter. For example, for a node running locally use `esdb://localhost:2113?tls=false`. Note that usernames and passwords aren't provided there because insecure deployments don't support authentication and authorisation. + +## Creating a client + +First, create a client and get it connected to the database. + +```java +EventStoreDBClientSettings settings = EventStoreDBConnectionString.parseOrThrow("esdb://localhost:2113?tls=false"); +EventStoreDBClient client = EventStoreDBClient.create(settings); +``` + +The client instance can be used as a singleton across the whole application. It doesn't need to open or close the connection. + +## Creating an event + +You can write anything to EventStoreDB as events. The client needs a byte array as the event payload. Normally, you'd use a serialized object, and it's up to you to choose the serialization method. + +The code snippet below creates an event object instance, serializes it, and adds it as a payload to the `EventData` structure, which the client can then write to the database. + +```java +public class OrderPlaced { + private String orderId; + private String customerId; + private double totalAmount; + private String status; + + public OrderPlaced(String orderId, String customerId, double totalAmount, String status) { + this.orderId = orderId; + this.customerId = customerId; + this.totalAmount = totalAmount; + this.status = status; + } +} + +OrderPlaced event = new OrderPlaced("order-456", "customer-789", 249.99, "confirmed"); +JsonMapper jsonMapper = new JsonMapper(); + +EventData eventData = EventData + .builderAsJson("OrderPlaced", jsonMapper.writeValueAsBytes(event)) + .build(); +``` + +## Appending events + +Each event in the database has its own unique identifier (UUID). The database uses it to ensure idempotent writes, but it only works if you specify the stream revision when appending events to the stream. + +In the snippet below, we append the event to the stream `orders`. + +```java +client.appendToStream("orders", eventData).get(); +``` + +Here we are appending events without checking if the stream exists or if the stream version matches the expected event version. See more advanced scenarios in [appending events documentation](./appending-events.md). + +## Reading events + +Finally, we can read events back from the `orders` stream. + +### Synchronous reading + +```java +import java.util.List; + +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromStart() + .maxCount(10); + +ReadResult result = client.readStream("orders", options) + .get(); + +List events = result.getEvents(); +``` + +### Asynchronous reading + +We also provide an asynchronous API for reading events using Java Reactive Streams. + +```java +import org.reactivestreams.Subscriber; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscription; + +import java.util.concurrent.CountDownLatch; + +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromStart() + .maxCount(10); + +Publisher publisher = client.readStreamReactive("orders", options); + +final CountDownLatch latch = new CountDownLatch(1); +publisher.subscribe(new Subscriber() { + @Override + public void onSubscribe(Subscription subscription) { + // subscription confirmed + } + + @Override + public void onNext(ReadMessage readMessage) { + // Process the event + RecordedEvent event = readMessage.getEvent().getOriginalEvent(); + } + + @Override + public void onError(Throwable throwable) { + // handle error + } + + @Override + public void onComplete() { + latch.countDown(); + } +}); + +latch.await(); +``` + +When you read events from the stream, you get a collection of `ResolvedEvent` +structures (synchronous) or `ReadMessage` objects (reactive). The event payload +is returned as a byte array and needs to be deserialized. See more advanced +scenarios in [reading events documentation](./reading-events.md). \ No newline at end of file diff --git a/docs/api/observability.md b/docs/api/observability.md new file mode 100644 index 00000000..e7c33568 --- /dev/null +++ b/docs/api/observability.md @@ -0,0 +1,182 @@ +--- +order: 8 +head: + - - title + - {} + - Observability | Java | Clients | EventStore Docs +--- + +# Observability + +The Java client provides observability capabilities through OpenTelemetry +integration. This enables you to monitor, trace, and troubleshoot your event +store operations with distributed tracing support. + +## Prerequisites + +You'll need to add OpenTelemetry dependencies to your project. Add these to your +Maven `pom.xml` or Gradle `build.gradle`: + +::: tabs#distribution +@tab Maven +```xml + + + + io.opentelemetry + opentelemetry-sdk + 1.40.0 + + + + + io.opentelemetry + opentelemetry-exporter-logging + 1.40.0 + + + + + io.opentelemetry + opentelemetry-exporter-otlp + 1.40.0 + + + + + io.opentelemetry.semconv + opentelemetry-semconv + 1.25.0-alpha + + +``` +@tab Gradle +```groovy +dependencies { + implementation 'io.opentelemetry:opentelemetry-sdk:1.40.0' + implementation 'io.opentelemetry:opentelemetry-exporter-logging:1.40.0' + implementation 'io.opentelemetry:opentelemetry-exporter-otlp:1.40.0' + implementation 'io.opentelemetry.semconv:opentelemetry-semconv:1.25.0-alpha' +} +``` +::: + +## Basic Configuration + +Configure OpenTelemetry by creating and registering the SDK with appropriate +exporters. Here's a minimal setup: + +```java +import com.eventstore.dbclient.*; +import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; + +import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME; + +public class EventStoreObservability { + public static void main(String[] args) { + // Configure resource with service name + Resource resource = Resource.getDefault().toBuilder() + .put(SERVICE_NAME, "my-eventstore-app") + .build(); + + // Create console exporter + LoggingSpanExporter consoleExporter = LoggingSpanExporter.create(); + + // Configure tracer provider + SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() + .addSpanProcessor(SimpleSpanProcessor.create(consoleExporter)) + .setResource(resource) + .build(); + + // Register OpenTelemetry SDK globally + OpenTelemetrySdk.builder() + .setTracerProvider(sdkTracerProvider) + .buildAndRegisterGlobal(); + + // Your EventStoreDB client operations will now be traced + EventStoreDBClientSettings settings = EventStoreDBConnectionString + .parseOrThrow("esdb://localhost:2113?tls=false"); + EventStoreDBClient client = EventStoreDBClient.create(settings); + } +} +``` + +## Trace Exporters + +OpenTelemetry supports various exporters to send trace data to different +observability platforms. You can find a list of available exporters in the +[OpenTelemetry Registry](https://opentelemetry.io/ecosystem/registry/?component=exporter&language=java). + +You can configure multiple exporters simultaneously: + +```java +import io.opentelemetry.exporter.logging.LoggingSpanExporter; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; + +import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME; + +public class MultipleExporters { + public static void configureOpenTelemetry() { + Resource resource = Resource.getDefault().toBuilder() + .put(SERVICE_NAME, "my-eventstore-app") + .build(); + + // Console/logging exporter + LoggingSpanExporter consoleExporter = LoggingSpanExporter.create(); + + // OTLP exporter for Jaeger/other OTLP-compatible backends + OtlpGrpcSpanExporter otlpExporter = OtlpGrpcSpanExporter.builder() + .setEndpoint("http://localhost:4317") + .build(); + + // Configure tracer provider with multiple exporters + SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() + .addSpanProcessor(SimpleSpanProcessor.create(consoleExporter)) + .addSpanProcessor(SimpleSpanProcessor.create(otlpExporter)) + .setResource(resource) + .build(); + + // Register globally + OpenTelemetrySdk.builder() + .setTracerProvider(sdkTracerProvider) + .buildAndRegisterGlobal(); + } +} +``` + +For detailed configuration options, refer to the +[OpenTelemetry Java documentation](https://opentelemetry.io/docs/languages/java/). + +## Understanding Traces + +### What Gets Traced + +The Java client automatically creates traces for append, catch-up and persistent +subscription operations when OpenTelemetry is configured globally. + +### Trace Attributes + +Each trace includes metadata to help with debugging and monitoring: + +| Attribute | Description | Example | +| --------------------------------- | -------------------------------------- | ------------------------------------- | +| `db.user` | Database user name | `admin` | +| `db.system` | Database system identifier | `eventstoredb` | +| `db.operation` | Type of operation performed | `streams.append`, `streams.subscribe` | +| `db.eventstoredb.stream` | Stream name or identifier | `user-events-123` | +| `db.eventstoredb.subscription.id` | Subscription identifier | `user-events-123-sub` | +| `db.eventstoredb.event.id` | Event identifier | `event-456` | +| `db.eventstoredb.event.type` | Event type identifier | `user.created` | +| `server.address` | EventStoreDB server address | `localhost` | +| `server.port` | EventStoreDB server port | `2113` | +| `exception.type` | Exception type if an error occurred | | +| `exception.message` | Exception message if an error occurred | | +| `exception.stacktrace` | Stack trace of the exception | | diff --git a/docs/api/persistent-subscriptions.md b/docs/api/persistent-subscriptions.md new file mode 100644 index 00000000..244ac6a1 --- /dev/null +++ b/docs/api/persistent-subscriptions.md @@ -0,0 +1,268 @@ +--- +order: 5 +head: + - - title + - {} + - Persistent Subscriptions | Java | Clients | EventStore Docs +--- + +# Persistent Subscriptions + +Persistent subscriptions are similar to catch-up subscriptions, but there are two key differences: + +- The subscription checkpoint is maintained by the server. It means that when +your client reconnects to the persistent subscription, it will automatically +resume from the last known position. +- It's possible to connect more than one event consumer to the same persistent +subscription. In that case, the server will load-balance the consumers, +depending on the defined strategy, and distribute the events to them. + +Because of those, persistent subscriptions are defined as subscription groups +that are defined and maintained by the server. Consumer then connect to a +particular subscription group, and the server starts sending event to the +consumer. + +You can read more about persistent subscriptions in the [server documentation](@server/features/persistent-subscriptions.md). + +## Creating a client + +The Java client provides a `PersistentSubscriptionsClient` that you can use to manage persistent subscriptions. + +```java +EventStoreDBClientSettings settings = EventStoreDBConnectionString.parseOrThrow("esdb://localhost:2113?tls=false"); +PersistentSubscriptionsClient client = PersistentSubscriptionsClient.create(settings); +``` + +## Creating a Subscription Group + +The first step in working with a persistent subscription is to create a +subscription group. Note that attempting to create a subscription group multiple +times will result in an error. Admin permissions are required to create a +persistent subscription group. + +The following examples demonstrate how to create a subscription group for a +persistent subscription. You can subscribe to a specific stream or to the `$all` +stream, which includes all events. + +### Subscribing to a Specific Stream + +```java +client.createToStream( + "stream-name", + "subscription-group", + CreatePersistentSubscriptionToStreamOptions.get() + .fromStart()); +``` + +### Subscribing to `$all` + +```java +client.createToAll( + "subscription-group", + CreatePersistentSubscriptionToAllOptions.get() + .fromStart()); + +``` + +::: note +As from EventStoreDB 21.10, the ability to subscribe to `$all` supports +[server-side filtering](subscriptions.md#server-side-filtering). You can create +a subscription group for `$all` similarly to how you would for a specific +stream: +::: + +## Connecting a consumer + +Once you have created a subscription group, clients can connect to it. A +subscription in your application should only have the connection in your code, +you should assume that the subscription already exists. + +The most important parameter to pass when connecting is the buffer size. This +represents how many outstanding messages the server should allow this client. If +this number is too small, your subscription will spend much of its time idle as +it waits for an acknowledgment to come back from the client. If it's too big, +you waste resources and can start causing time out messages depending on the +speed of your processing. + +### Connecting to one stream + +The code below shows how to connect to an existing subscription group for a specific stream: + +```java +client.subscribeToStream( + "stream-name", + "subscription-group", + new PersistentSubscriptionListener() { + @Override + public void onEvent(PersistentSubscription subscription, int retryCount, ResolvedEvent event) { + System.out.println("Received event" + + event.getOriginalEvent().getRevision() + + "@" + event.getOriginalEvent().getStreamId()); + } + + @Override + public void onCancelled(PersistentSubscription subscription, Throwable exception) { + if (exception == null) { + System.out.println("Subscription is cancelled"); + return; + } + + System.out.println("Subscription was dropped due to " + exception.getMessage()); + } + }); +``` + +### Connecting to $all + +The code below shows how to connect to an existing subscription group for `$all`: + +```java +client.subscribeToAll( + "subscription-group", + new PersistentSubscriptionListener() { + @Override + public void onEvent(PersistentSubscription subscription, int retryCount, ResolvedEvent event) { + try { + System.out.println("Received event" + + event.getOriginalEvent().getRevision() + + "@" + event.getOriginalEvent().getStreamId()); + subscription.ack(event); + } + catch (Exception ex) { + subscription.nack(NackAction.Park, ex.getMessage(), event); + } + } + + public void onCancelled(PersistentSubscription subscription, Throwable exception) { + if (exception == null) { + System.out.println("Subscription is cancelled"); + return; + } + + System.out.println("Subscription was dropped due to " + exception.getMessage()); + } + }); +``` + +The `SubscribeToAll` method is identical to the `SubscribeToStream` method, except that you don't need to specify a stream name. + +## Acknowledgements + +Clients must acknowledge (or not acknowledge) messages in the competing consumer model. + +If processing is successful, you must send an Ack (acknowledge) to the server to +let it know that the message has been handled. If processing fails for some +reason, then you can Nack (not acknowledge) the message and tell the server how +to handle the failure. + +```java +client.subscribeToStream( + "test-stream", + "subscription-group", + new PersistentSubscriptionListener() { + @Override + public void onEvent(PersistentSubscription subscription, int retryCount, ResolvedEvent event) { + try { + System.out.println("Received event" + + event.getOriginalEvent().getRevision() + + "@" + event.getOriginalEvent().getStreamId()); + subscription.ack(event); + } + catch (Exception ex) { + subscription.nack(NackAction.Park, ex.getMessage(), event); + } + } + }); +``` + +The _Nack event action_ describes what the server should do with the message: + +| Action | Description | +|:----------|:---------------------------------------------------------------------| +| `Unknown` | The client does not know what action to take. Let the server decide. | +| `Park` | Park the message and do not resend. Put it on poison queue. | +| `Retry` | Explicitly retry the message. | +| `Skip` | Skip this message do not resend and do not put in poison queue. | +| `Stop` | Stop the subscription. | + +## Consumer strategies + +When creating a persistent subscription, you can choose between a number of consumer strategies. + +### RoundRobin (default) + +Distributes events to all clients evenly. If the client `bufferSize` is reached, +the client won't receive more events until it acknowledges or not acknowledges +events in its buffer. + +This strategy provides equal load balancing between all consumers in the group. + +### DispatchToSingle + +Distributes events to a single client until the `bufferSize` is reached. After +that, the next client is selected in a round-robin style, and the process +repeats. + +This option can be seen as a fall-back scenario for high availability, when a +single consumer processes all the events until it reaches its maximum capacity. +When that happens, another consumer takes the load to free up the main consumer +resources. + +### Pinned + +For use with an indexing projection such as the system `$by_category` projection. + +EventStoreDB inspects the event for its source stream id, hashing the id to one +of 1024 buckets assigned to individual clients. When a client disconnects, its +buckets are assigned to other clients. When a client connects, it is assigned +some existing buckets. This naively attempts to maintain a balanced workload. + +The main aim of this strategy is to decrease the likelihood of concurrency and +ordering issues while maintaining load balancing. This is **not a guarantee**, +and you should handle the usual ordering and concurrency issues. + +## Updating a subscription group + +You can edit the settings of an existing subscription group while it is running, +you don't need to delete and recreate it to change settings. When you update the +subscription group, it resets itself internally, dropping the connections and +having them reconnect. You must have admin permissions to update a persistent +subscription group. + +```java +client.updateToStream( + "stream-name", + "subscription-group", + UpdatePersistentSubscriptionToStreamOptions.get() + .resolveLinkTos() + .checkpointLowerBound(20)); +``` + +## Persistent subscription settings + +Both the `Create` and `Update` methods take some settings for configuring the persistent subscription. + +The following table shows the configuration options you can set on a persistent subscription. + +| Option | Description | Default | +| :---------------------- | :-------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------- | +| `resolveLinkTos` | Whether the subscription should resolve link events to their linked events. | `false` | +| `fromStart` | The exclusive position in the stream or transaction file the subscription should start from. | `null` (start from the end of the stream) | +| `extraStatistics` | Whether to track latency statistics on this subscription. | `false` | +| `messageTimeout` | The amount of time after which to consider a message as timed out and retried. | `30` (seconds) | +| `maxRetryCount` | The maximum number of retries (due to timeout) before a message is considered to be parked. | `10` | +| `liveBufferSize` | The size of the buffer (in-memory) listening to live messages as they happen before paging occurs. | `500` | +| `readBatchSize` | The number of events read at a time when paging through history. | `20` | +| `historyBufferSize` | The number of events to cache when paging through history. | `500` | +| `checkpointLowerBound` | The minimum number of messages to process before a checkpoint may be written. | `10` seconds | +| `checkpointUpperBound` | The maximum number of messages not checkpoint before forcing a checkpoint. | `1000` | +| `maxSubscriberCount` | The maximum number of subscribers allowed. | `0` (unbounded) | +| `namedConsumerStrategy` | The strategy to use for distributing events to client consumers. See the [consumer strategies](#consumer-strategies) in this doc. | `RoundRobin` | + +## Deleting a subscription group + +Remove a subscription group with the delete operation. Like the creation of groups, you rarely do this in your runtime code and is undertaken by an administrator running a script. + +```java +client.deleteToStream("stream-name", "subscription-group"); +``` diff --git a/docs/api/projections.md b/docs/api/projections.md new file mode 100644 index 00000000..6afd23a5 --- /dev/null +++ b/docs/api/projections.md @@ -0,0 +1,369 @@ +--- +order: 6 +title: Projections +head: + - - title + - {} + - Projections | Java | Clients | EventStore Docs +--- + +# Projection management + +The client provides a way to manage projections in EventStoreDB. + +For a detailed explanation of projections, see the [server documentation](@server/features/projections/README.md). + +## Creating a client + +The Java client provides a `EventStoreDBProjectionManagementClient` that you can use to manage persistent subscriptions. + +```java +EventStoreDBClientSettings settings = EventStoreDBConnectionString.parseOrThrow("esdb://localhost:2113?tls=false"); +EventStoreDBProjectionManagementClient client = EventStoreDBProjectionManagementClient.create(settings); +``` + +## Create a projection + +Creates a projection that runs until the last event in the store, and then continues processing new events as they are appended to the store. The query parameter contains the JavaScript you want created as a projection. +Projections have explicit names, and you can enable or disable them via this name. + +```java +String js = + "fromAll()" + + ".when({" + + " $init: function() {" + + " return {" + + " count: 0" + + " };" + + " }," + + " $any: function(s, e) {" + + " s.count += 1;" + + " }" + + "})" + + ".outputState();"; + +String name = "countEvents_Create_" + java.util.UUID.randomUUID(); + +client.create(name, js).get(); +``` + +Trying to create projections with the same name will result in an error: + +```java +try { + client.create(name, js).get(); +} catch (ExecutionException ex) { + if (ex.getMessage().contains("Conflict")) { + System.out.println(name + " already exists"); + } +} +``` + +## Restart the subsystem + +It is possible to restart the entire projection subsystem using the projections management client API. The user must be in the `$ops` or `$admin` group to perform this operation. + +```java +client.restartSubsystem().get(); +``` + +## Enable a projection + +This Enables an existing projection by name. Once enabled, the projection will +start to process events even after restarting the server or the projection +subsystem. You must have access to a projection to enable it, see the [ACL documentation](@server/security/user-authorization.md). + +```java +client.enable("$by_category").get(); +``` + +You can only enable an existing projection. When you try to enable a non-existing projection, you'll get an error: + + ```java +try { + client.disable("projection that does not exists").get(); +} catch (ExecutionException ex) { + if (ex.getMessage().contains("NotFound")) { + System.out.println(ex.getMessage()); + } +} +``` + +## Disable a projection + +Disables a projection, this will save the projection checkpoint. +Once disabled, the projection will not process events even after restarting the server or the projection subsystem. +You must have access to a projection to disable it, see the [ACL documentation](@server/security/user-authorization.md). + +```java +client.disable("$by_category").get(); +``` + +You can only disable an existing projection. When you try to disable a non-existing projection, you'll get an error: + +```java +try { + client.disable("projection that does not exists").get(); +} catch (ExecutionException ex) { + if (ex.getMessage().contains("NotFound")) { + System.out.println(ex.getMessage()); + } +} +``` + +## Delete a projection + +```java +// A projection must be disabled to allow it to be deleted. +client.disable(name).get(); + +// The projection can now be deleted +client.delete(name).get(); +``` + +## Abort a projection + +Aborts a projection, this will not save the projection's checkpoint. + +```java +client.abort("$by_category").get(); +``` + +You can only abort an existing projection. When you try to abort a non-existing projection, you'll get an error: + +```java +try { + client.abort("projection that does not exists").get(); +} catch (ExecutionException ex) { + if (ex.getMessage().contains("NotFound")) { + System.out.println(ex.getMessage()); + } +} +``` + +## Reset a projection + +Resets a projection, which causes deleting the projection checkpoint. This will force the projection to start afresh and re-emit events. Streams that are written to from the projection will also be soft-deleted. + +```java +client.reset("$by_category").get(); +``` + +Resetting a projection that does not exist will result in an error. + +```java +try { + client.reset("projection that does not exists").get(); +} catch (ExecutionException ex) { + if (ex.getMessage().contains("NotFound")) { + System.out.println(ex.getMessage()); + } +} +``` + +## Update a projection + +Updates a projection with a given name. The query parameter contains the new JavaScript. Updating system projections using this operation is not supported at the moment. + +```java +String name = "countEvents_Update_" + java.util.UUID.randomUUID(); +String js = + "fromAll()" + + ".when({" + + " $init: function() {" + + " return {" + + " count: 0" + + " };" + + " }," + + " $any: function(s, e) {" + + " s.count += 1;" + + " }" + + "})" + + ".outputState();"; + +client.create(name, "fromAll().when()").get(); +client.update(name, js).get(); +``` + +You can only update an existing projection. When you try to update a non-existing projection, you'll get an error: + +```java +try { + client.update("Update Not existing projection", "fromAll().when()").get(); +} catch (ExecutionException ex) { + if (ex.getMessage().contains("NotFound")) { + System.out.println("'Update Not existing projection' does not exists and can not be updated"); + } +} +``` + +## List all projections + +Returns a list of all projections, user defined & system projections. +See the [projection details](#projection-details) section for an explanation of the returned values. + +```java +List details = client.list().get(); + +for (ProjectionDetails detail: details) { + System.out.println( + detail.getName() + ", " + + detail.getStatus() + ", " + + detail.getCheckpointStatus() + ", " + + detail.getMode() + ", " + + detail.getProgress()); +} +``` + +## List continuous projections + +Returns a list of all continuous projections. +See the [projection details](#projection-details) section for an explanation of the returned values. + +```java +List details = client.list().get(); + +for (ProjectionDetails detail: details) { + System.out.println( + detail.getName() + ", " + + detail.getStatus() + ", " + + detail.getCheckpointStatus() + ", " + + detail.getMode() + ", " + + detail.getProgress()); +} +``` + +## Get status + +Gets the status of a named projection. +See the [projection details](#projection-details) section for an explanation of the returned values. + +```java +ProjectionDetails status = client.getStatus("$by_category").get(); +System.out.println( + status.getName() + ", " + + status.getStatus() + ", " + + status.getCheckpointStatus() + ", " + + status.getMode() + ", " + + status.getProgress()); +``` + +## Get state + +Retrieves the state of a projection. + +```java +public static class CountResult { + private int count; + public int getCount() { + return count; + } + public void setCount(final int count){ + this.count = count; + } +} + +String name = "get_state_example"; +String js = + "fromAll()" + + ".when({" + + " $init() {" + + " return {" + + " count: 0," + + " };" + + " }," + + " $any(s, e) {" + + " s.count += 1;" + + " }" + + "})" + + ".outputState();"; + +client.create(name, js).get(); + +Thread.sleep(500); //give it some time to process and have a state. + +CountResult result = client + .getState(name, CountResult.class) + .get(); + +System.out.println(result); +``` + +## Get result + +Retrieves the result of the named projection and partition. + +```java +String name = "get_result_example"; +String js = + "fromAll()" + + ".when({" + + " $init() {" + + " return {" + + " count: 0," + + " };" + + " }," + + " $any(s, e) {" + + " s.count += 1;" + + " }" + + "})" + + ".transformBy((state) => state.count)" + + ".outputState();"; + +client.create(name, js).get(); + +Thread.sleep(500); //give it some time to process and have a state. + +int result = client + .getResult(name, int.class) + .get(); + +System.out.println(result); +``` + +## Projection Details + +The `list`, and `getStatus` methods return detailed statistics and information +about projections. Below is an explanation of the fields included in the +projection details: + +| Field | Description | +| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `name`, `effectiveName` | The name of the projection | +| `status` | A human readable string of the current statuses of the projection (see below) | +| `stateReason` | A human readable string explaining the reason of the current projection state | +| `checkpointStatus` | A human readable string explaining the current operation performed on the checkpoint : `requested`, `writing` | +| `mode` | `Continuous`, `OneTime` , `Transient` | +| `coreProcessingTime` | The total time, in ms, the projection took to handle events since the last restart | +| `progress` | The progress, in %, indicates how far this projection has processed event, in case of a restart this could be -1% or some number. It will be updated as soon as a new event is appended and processed | +| `writesInProgress` | The number of write requests to emitted streams currently in progress, these writes can be batches of events | +| `readsInProgress` | The number of read requests currently in progress | +| `partitionsCached` | The number of cached projection partitions | +| `position` | The Position of the last processed event | +| `lastCheckpoint` | The Position of the last checkpoint of this projection | +| `eventsProcessedAfterRestart` | The number of events processed since the last restart of this projection | +| `bufferedEvents` | The number of events in the projection read buffer | +| `writePendingEventsBeforeCheckpoint` | The number of events waiting to be appended to emitted streams before the pending checkpoint can be written | +| `writePendingEventsAfterCheckpoint` | The number of events to be appended to emitted streams since the last checkpoint | +| `version` | This is used internally, the version is increased when the projection is edited or reset | +| `epoch` | This is used internally, the epoch is increased when the projection is reset | + +The `status` string is a combination of the following values. + +The first 3 are the most common one, as the other one are transient values while +the projection is initialised or stopped + +| Value | Description | +|--------------------|-------------------------------------------------------------------------------------------------------------------------| +| Running | The projection is running and processing events | +| Stopped | The projection is stopped and is no longer processing new events | +| Faulted | An error occurred in the projection, `StateReason` will give the fault details, the projection is not processing events | +| Initial | This is the initial state, before the projection is fully initialised | +| Suspended | The projection is suspended and will not process events, this happens while stopping the projection | +| LoadStateRequested | The state of the projection is being retrieved, this happens while the projection is starting | +| StateLoaded | The state of the projection is loaded, this happens while the projection is starting | +| Subscribed | The projection has successfully subscribed to its readers, this happens while the projection is starting | +| FaultedStopping | This happens before the projection is stopped due to an error in the projection | +| Stopping | The projection is being stopped | +| CompletingPhase | This happens while the projection is stopping | +| PhaseCompleted | This happens while the projection is stopping | diff --git a/docs/api/reading-events.md b/docs/api/reading-events.md new file mode 100644 index 00000000..8216ffc1 --- /dev/null +++ b/docs/api/reading-events.md @@ -0,0 +1,388 @@ +--- +order: 3 +head: + - - title + - {} + - Reading Events | Java | Clients | EventStore Docs +--- + +# Reading Events + +EventStoreDB provides two primary methods for reading events: reading from an +individual stream to retrieve events from a specific named stream, or reading +from the `$all` stream to access all events across the entire event store. + +Events in EventStoreDB are organized within individual streams and use two +distinct positioning systems to track their location. The **revision number** is +a 64-bit signed integer (`long`) that represents the sequential position of an +event within its specific stream. Events are numbered starting from 0, with each +new event receiving the next sequential revision number (0, 1, 2, 3...). The +**global position** represents the event's location in EventStoreDB's global +transaction log and consists of two coordinates: the `commit` position (where +the transaction was committed in the log) and the `prepare` position (where the +transaction was initially prepared). + +These positioning identifiers are essential for reading operations, as they +allow you to specify exactly where to start reading from within a stream or +across the entire event store. + +## Reading from a stream + +You can read all the events or a sample of the events from individual streams, +starting from any position in the stream, and can read either forward or +backward. It is only possible to read events from a single stream at a time. You +can read events from the global event log, which spans across streams. Learn +more about this process in the [Read from `$all`](#reading-from-the-all-stream) +section below. + +### Reading forwards + +The simplest way to read a stream forwards is to supply a stream name, read +direction, and revision from which to start. The revision can be specified in several ways: + +- Use `fromStart()` to begin from the very beginning of the stream +- Use `fromEnd()` to begin from the current end of the stream +- Use `fromRevision(long revision)` with a specific revision number (64-bit signed integer) + +```java{3} +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromStart(); + +ReadResult result = client.readStream("orders", options) + .get(); +``` + +You can also start reading from a specific revision in the stream: + +```java{3} +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromRevision(10); + +ReadResult result = client.readStream("orders", options) + .get(); +``` + +You can then iterate synchronously through the result: + +```java +import com.fasterxml.jackson.databind.json.JsonMapper; + +JsonMapper mapper = new JsonMapper(); + +for (ResolvedEvent resolvedEvent : result.getEvents()) { + RecordedEvent recordedEvent = resolvedEvent.getOriginalEvent(); + System.out.println(mapper.writeValueAsString(recordedEvent.getEventData())); +} +``` + +There are a number of additional arguments you can provide when reading a stream. + +#### maxCount + +Passing in the max count allows you to limit the number of events that returned. + +```java{4} +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromRevision(10) + .maxCount(20); +``` + +#### resolveLinkTos + +When using projections to create new events you can set whether the generated events are pointers to existing events. Setting this value to true will tell EventStoreDB to return the event as well as the event linking to it. + +```java{4} +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromStart() + .resolveLinkTos(); + +ReadResult result = client.readStream("orders", options) + .get(); +``` + +#### userCredentials + +The credentials used to read the data can be used by the subscription as follows. This will override the default credentials set on the connection. + +```java{4} +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromStart() + .authenticated("admin", "changeit"); + +ReadResult result = client.readStream("orders", options) + .get(); +``` + +### Reading backwards + +In addition to reading a stream forwards, streams can be read backwards. To read all the events backwards, set the *stream position* to the end: + +```java{4} +JsonMapper mapper = new JsonMapper(); + +ReadStreamOptions options = ReadStreamOptions.get() + .backwards() + .fromEnd(); + +ReadResult result = client.readStream("orders", options) + .get(); + +for (ResolvedEvent resolvedEvent : result.getEvents()) { + RecordedEvent recordedEvent = resolvedEvent.getOriginalEvent(); + System.out.println(mapper.writeValueAsString(recordedEvent.getEventData())); +} +``` + +:::tip +Read one event backwards to find the last position in the stream. +::: + +### Checking if the stream exists + +Reading a stream returns a `ReadStreamResult`, which contains a property `ReadState`. This property can have the value `StreamNotFound` or `Ok`. + +It is important to check the value of this field before attempting to iterate an empty stream, as it will throw an exception. + +For example: + +```java{11-15} +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromRevision(10) + .maxCount(20); + +ReadResult result = null; +try { + result = client.readStream("some-stream", options) + .get(); +} catch (ExecutionException e) { + Throwable innerException = e.getCause(); + + if (innerException instanceof StreamNotFoundException) { + return; + } +} +``` + +## Reading from the $all stream + +Reading from the `$all` stream is similar to reading from an individual stream, but please note there are differences. One significant difference is the need to provide admin user account credentials to read from the `$all` stream. Additionally, you need to provide a transaction log position instead of a stream revision when reading from the `$all` stream. + +### Reading forwards + +The simplest way to read the `$all` stream forwards is to supply a read +direction and the transaction log position from which you want to start. The +transaction log position can be specified in several ways: + +- Use `fromStart()` to begin from the very beginning of the transaction log +- Use `fromEnd()` to begin from the current end of the transaction log +- Use `fromPosition(Position position)` with a specific `Position` object containing commit and prepare coordinates + +```java{2-3} +ReadAllOptions options = ReadAllOptions.get() + .forwards() + .fromStart(); + +ReadResult result = client.readAll(options) + .get(); +``` + +You can also start reading from a specific position in the transaction log: + +```java{1,4-5} +Position position = new Position(1000, 1000); + +ReadAllOptions options = ReadAllOptions.get() + .forwards() + .fromPosition(position); + +ReadResult result = client.readAll(options) + .get(); +``` + +You can then iterate synchronously through the result: + +```java +import com.fasterxml.jackson.databind.json.JsonMapper; + +JsonMapper mapper = new JsonMapper(); + +for (ResolvedEvent resolvedEvent : result.getEvents()) { + RecordedEvent recordedEvent = resolvedEvent.getOriginalEvent(); + System.out.println(mapper.writeValueAsString(recordedEvent.getEventData())); +} +``` + +There are a number of additional arguments you can provide when reading the `$all` stream. + +#### maxCount + +Passing in the max count allows you to limit the number of events that returned. + +```java{4} +ReadAllOptions options = ReadAllOptions.get() + .forwards() + .fromRevision(10) + .maxCount(20); +``` + +#### resolveLinkTos + +When using projections to create new events you can set whether the generated events are pointers to existing events. Setting this value to true will tell EventStoreDB to return the event as well as the event linking to it. + +```java{4} +ReadAllOptions options = ReadAllOptions.get() + .forwards() + .fromStart() + .resolveLinkTos(); + +ReadResult result = client.readAll(options) + .get(); +``` + +#### userCredentials +The credentials used to read the data can be used by the subscription as follows. This will override the default credentials set on the connection. + +```java{4} +ReadAllOptions options = ReadAllOptions.get() + .forwards() + .fromStart() + .authenticated("admin", "changeit"); + +ReadResult result = client.readAll(options) + .get(); +``` + +### Reading backwards + +In addition to reading the `$all` stream forwards, it can be read backwards. To +read all the events backwards, set the _direction_ to the `Backwards`: + +```java{2} +ReadAllOptions options = ReadAllOptions.get() + .backwards() + .fromEnd(); + +ReadResult result = client.readAll(options) + .get(); +``` + +:::tip +Read one event backwards to find the last position in the `$all` stream. +::: + +### Handling system events + +EventStoreDB will also return system events when reading from the `$all` stream. In most cases you can ignore these events. + +All system events begin with `$` or `$$` and can be easily ignored by checking the `eventType` property. + +```java{10-12} +ReadAllOptions options = ReadAllOptions.get() + .forwards() + .fromStart(); + +ReadResult result = client.readAll(options) + .get(); + +for (ResolvedEvent resolvedEvent : result.getEvents()) { + RecordedEvent recordedEvent = resolvedEvent.getOriginalEvent(); + if (!recordedEvent.getEventType().startsWith("$")) { + // Process the event + } +} +``` + +## Java Reactive Streams + +The Java Reactive Streams API allows you to read events in a non-blocking manner, which is particularly useful for applications that require high throughput and low latency. The reactive API provides a way to subscribe to streams of events and process them as they arrive. + +::: tabs#java +@tab Reading from a stream +```java +import org.reactivestreams.Subscriber; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscription; +import java.util.concurrent.CountDownLatch; + +ReadStreamOptions options = ReadStreamOptions.get() + .forwards() + .fromStart(); + +Publisher publisher = client.readStreamReactive("orders", options); + +final CountDownLatch latch = new CountDownLatch(1); +publisher.subscribe(new Subscriber() { + @Override + public void onSubscribe(Subscription subscription) { + } + + @Override + public void onNext(ReadMessage readMessage) { + RecordedEvent event = readMessage.getEvent().getOriginalEvent(); + // Process the event + System.out.println("Event: " + event.getEventType()); + } + + @Override + public void onError(Throwable throwable) { + // Handle error + latch.countDown(); + } + + @Override + public void onComplete() { + latch.countDown(); + } +}); + +latch.await(); +``` +@tab Reading from $all +```java +import org.reactivestreams.Subscriber; +import org.reactivestreams.Publisher; +import org.reactivestreams.Subscription; +import java.util.concurrent.CountDownLatch; + +ReadAllOptions options = ReadAllOptions.get() + .forwards() + .fromStart(); + +Publisher publisher = client.readAllReactive(options); + +final CountDownLatch latch = new CountDownLatch(1); +publisher.subscribe(new Subscriber() { + @Override + public void onSubscribe(Subscription subscription) { + } + + @Override + public void onNext(ReadMessage readMessage) { + RecordedEvent event = readMessage.getEvent().getOriginalEvent(); + // Filter out system events if needed + if (!event.getEventType().startsWith("$")) { + System.out.println("Event: " + event.getEventType()); + } + } + + @Override + public void onError(Throwable throwable) { + // Handle error + latch.countDown(); + } + + @Override + public void onComplete() { + latch.countDown(); + } +}); + +latch.await(); +``` +::: \ No newline at end of file diff --git a/docs/api/subscriptions.md b/docs/api/subscriptions.md new file mode 100644 index 00000000..df4b2832 --- /dev/null +++ b/docs/api/subscriptions.md @@ -0,0 +1,408 @@ +--- +order: 4 +head: + - - title + - {} + - Catch-up Subscriptions | Java | Clients | EventStore Docs +--- + +# Catch-up Subscriptions + +Subscriptions allow you to subscribe to a stream and receive notifications about new events added to the stream. You provide an event handler and an optional starting point to the subscription. The handler is called for each event from the starting point onward. + +If events already exist, the handler will be called for each event one by one until it reaches the end of the stream. The server will then notify the handler whenever a new event appears. + +:::tip +Check the [Getting Started](getting-started.md) guide to learn how to configure and use the client SDK. +::: + +## Basic Subscriptions + +You can subscribe to a single stream or to `$all` to process all events in the database. + +**Stream subscription:** + +```java +SubscriptionListener listener = new SubscriptionListener() { + @Override + public void onEvent(Subscription subscription, ResolvedEvent event) { + System.out.println("Received event" + + event.getOriginalEvent().getRevision() + + "@" + event.getOriginalEvent().getStreamId()); + // Handle the event + } +}; + +client.subscribeToStream("orders", listener); +``` + +**`$all` subscription:** + +```java +client.subscribeToAll(listener); +``` + +When you subscribe to a stream with link events (e.g., `$ce` category stream), set `resolveLinkTos` to `true`. + +## Subscribing from a Position + +Both stream and `$all` subscriptions accept a starting position if you want to read from a specific point onward. If events already exist at the position you subscribe to, they will be read on the server side and sent to the subscription. + +Once caught up, the server will push any new events received on the streams to the client. There is no difference between catching up and live on the client side. + +::: warning +The positions provided to the subscriptions are exclusive. You will only receive the next event after the subscribed position. +::: + +**Stream from specific position:** + +To subscribe to a stream from a specific position, provide a stream position (`fromStart()`, `fromEnd()` or a 64-bit signed integer representing the revision number): + +```java +client.subscribeToStream( + "orders", + listener, + SubscribeToStreamOptions.get() + .fromRevision(20) +); +``` + +**`$all` from specific position:** + +For the `$all` stream, provide a `Position` structure with prepare and commit positions: + +```java +client.subscribeToAll( + listener, + SubscribeToAllOptions.get() + .fromPosition(new Position(1056, 1056)) +); +``` + +**Live updates only:** + +Subscribe to the end of a stream to get only new events: + +```java +// Stream +client.subscribeToStream( + "orders", + listener, + SubscribeToStreamOptions.get() + .fromEnd() +); + +// $all +client.subscribeToAll( + listener, + SubscribeToAllOptions.get() + .fromEnd() +); +``` + +## Resolving link-to events + +Link-to events point to events in other streams in EventStoreDB. These are +generally created by projections such as the `$by_event_type` projection which +links events of the same event type into the same stream. This makes it easier +to look up all events of a specific type. + +::: tip +[Filtered subscriptions](subscriptions.md#server-side-filtering) make it easier +and faster to subscribe to all events of a specific type or matching a prefix. +::: + +When reading a stream you can specify whether to resolve link-to's. By default, +link-to events are not resolved. You can change this behaviour by setting the +`resolveLinkTos` parameter to `true`: + +```java +client.subscribeToStream( + "$et-orders", + listener, + SubscribeToStreamOptions.get() + .fromStart() + .resolveLinkTos() +); +``` + +## Subscription Drops and Recovery + +When a subscription stops or experiences an error, it will be dropped. The +subscription provides an `onCancelled` callback in the `SubscriptionListener`, +which will get called when the subscription breaks. + +The `onCancelled` callback allows you to inspect the reason why the +subscription dropped, as well as any exceptions that occurred. + +Bear in mind that a subscription can also drop because it is slow. The server +tried to push all the live events to the subscription when it is in the live +processing mode. If the subscription gets the reading buffer overflow and won't +be able to acknowledge the buffer, it will break. + +### Handling Dropped Subscriptions + +An application, which hosts the subscription, can go offline for some time for +different reasons. It could be a crash, infrastructure failure, or a new version +deployment. As you rarely would want to reprocess all the events again, you'd +need to store the current position of the subscription somewhere, and then use +it to restore the subscription from the point where it dropped off: + +```java +client.subscribeToStream( + "orders", + new SubscriptionListener() { + StreamPosition checkpoint = StreamPosition.start(); + @Override + public void onEvent(Subscription subscription, ResolvedEvent event) { + HandleEvent(event); + checkpoint = StreamPosition.position(event.getOriginalEvent().getRevision()); + } + + @Override + public void onCancelled(Subscription subscription, Throwable exception) { + // Subscription was dropped by the user. + if (exception == null) + return; + + System.out.println("Subscription was dropped due to " + exception.getMessage()); + Resubscribe(checkpoint); + } + }, + SubscribeToStreamOptions.get() + .fromStart() +); +``` + +When subscribed to `$all` you want to keep the event's position in the `$all` +stream. As mentioned previously, the `$all` stream position consists of two big +integers (prepare and commit positions), not one: + +```java +client.subscribeToAll( + new SubscriptionListener() { + StreamPosition checkpoint = StreamPosition.start(); + @Override + public void onEvent(Subscription subscription, ResolvedEvent event) { + HandleEvent(event); + checkpoint = StreamPosition.position(event.getOriginalEvent().getPosition()); + } + + @Override + public void onCancelled(Subscription subscription, Throwable exception) { + // Subscription was dropped by the user. + if (exception == null) + return; + + System.out.println("Subscription was dropped due to " + exception.getMessage()); + Resubscribe(checkpoint); + } + }, + SubscribeToAllOptions.get() + .fromStart() +); +``` + +## Handling Subscription State Changes + +::: info EventStoreDB 23.10.0+ +This feature requires EventStoreDB version 23.10.0 or later. +::: + +When a subscription processes historical events and reaches the end of the +stream, it transitions from "catching up" to "live" mode. You can detect this +transition using the `onCaughtUp` callback in the `SubscriptionListener`. + +```java +SubscriptionListener listener = new SubscriptionListener() { + @Override + public void onEvent(Subscription subscription, ResolvedEvent event) { + System.out.println("Processing event: " + event.getOriginalEvent().getEventType()); + // Handle the event + } + + @Override + public void onCaughtUp(Subscription subscription) { + System.out.println("Subscription caught up - now processing live events"); + // Trigger any actions needed when caught up + } + + @Override + public void onCancelled(Subscription subscription, Throwable exception) { + if (exception != null) { + System.out.println("Subscription dropped: " + exception.getMessage()); + } + } +}; + +client.subscribeToStream("orders", listener); +``` + +::: tip +The `onCaughtUp` callback is only triggered when transitioning from catching up to live mode. If you subscribe from the end of a stream, you'll immediately be in live mode and this callback will be called right away. +::: + + +## User credentials + +The user creating a subscription must have read access to the stream it's +subscribing to, and only admin users may subscribe to `$all` or create filtered +subscriptions. + +The code below shows how you can provide user credentials for a subscription. +When you specify subscription credentials explicitly, it will override the +default credentials set for the client. If you don't specify any credentials, +the client will use the credentials specified for the client, if you specified +those. + +```java +UserCredentials credentials = new UserCredentials("admin", "changeit"); + +SubscribeToAllOptions options = SubscribeToAllOptions.get().authenticated(credentials); + +client.subscribeToAll(listener, options); +``` + +## Server-side Filtering + +EventStoreDB allows you to filter events while subscribing to the `$all` stream to only receive the events you care about. You can filter by event type or stream name using a regular expression or a prefix. Server-side filtering is currently only available on the `$all` stream. + +::: tip +Server-side filtering was introduced as a simpler alternative to projections. You should consider filtering before creating a projection to include the events you care about. +::: + +**Basic filtering:** + +```java +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .addStreamNamePrefix("test-") + .build(); + +SubscribeToAllOptions options = SubscribeToAllOptions.get() + .filter(filter); + +client.subscribeToAll(listener, options); +``` + +### Filtering out system events + +System events are prefixed with `$` and can be filtered out when subscribing to `$all`: + +```java +String excludeSystemEventsRegex = "^[^\\$].*"; + +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .withEventTypeRegularExpression(excludeSystemEventsRegex) + .build(); + +client.subscribeToAll(listener, SubscribeToAllOptions.get().filter(filter)); +``` + +### Filtering by event type + +**By prefix:** + +```java +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .addEventTypePrefix("customer-") + .build(); +``` + +**By regular expression:** + +```java +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .withEventTypeRegularExpression("^user|^company") + .build(); +``` + +### Filtering by stream name + +**By prefix:** + +```java +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .addStreamNamePrefix("user-") + .build(); +``` + +**By regular expression:** + +```java +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .withStreamNameRegularExpression("^account|^savings") + .build(); +``` + +## Checkpointing + +When a catch-up subscription is used to process an `$all` stream containing many events, the last thing you want is for your application to crash midway, forcing you to restart from the beginning. + +### What is a checkpoint? + +A checkpoint is the position of an event in the `$all` stream to which your application has processed. By saving this position to a persistent store (e.g., a database), it allows your catch-up subscription to: + +- Recover from crashes by reading the checkpoint and resuming from that position +- Avoid reprocessing all events from the start + +To create a checkpoint, store the event's commit or prepare position. + +::: warning +If your database contains events created by the legacy TCP client using the [transaction feature](https://docs.kurrent.io/clients/tcp/dotnet/21.2/appending.html#transactions), you should store both the commit and prepare positions together as your checkpoint. +::: + +### Updating checkpoints at regular intervals + +The SDK provides a way to notify your application after processing a configurable number of events. This allows you to periodically save a checkpoint at regular intervals. + +```java +String excludeSystemEventsRegex = "/^[^\\$].*/"; + +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .withEventTypeRegularExpression(excludeSystemEventsRegex) + .withCheckpointer( + new Checkpointer() { + @Override + public CompletableFuture onCheckpoint(Subscription subscription, Position position) { + // Save commit position to a persistent store as a checkpoint + System.out.println("checkpoint taken at {position.getCommitUnsigned}"); + return CompletableFuture.completedFuture(null); + } + }) + .build(); +``` + +By default, the checkpoint notification is sent after every 32 non-system events processed from $all. + +### Configuring the checkpoint interval + +You can adjust the checkpoint interval to change how often the client is notified. + +```java +String excludeSystemEventsRegex = "/^[^\\$].*/"; + +SubscriptionFilter filter = SubscriptionFilter.newBuilder() + .withEventTypeRegularExpression(excludeSystemEventsRegex) + .withCheckpointer( + new Checkpointer() { + @Override + public CompletableFuture onCheckpoint(Subscription subscription, Position position) { + // Save commit position to a persistent store as a checkpoint + System.out.println("checkpoint taken at {position.getCommitUnsigned}"); + return CompletableFuture.completedFuture(null); + } + }, + 1000) + .build(); +``` + +By configuring this parameter, you can balance between reducing checkpoint overhead and ensuring quick recovery in case of a failure. + +::: info +The checkpoint interval parameter configures the database to notify the client after `n` * 32 number of events where `n` is defined by the parameter. + +For example: +- If `n` = 1, a checkpoint notification is sent every 32 events. +- If `n` = 2, the notification is sent every 64 events. +- If `n` = 3, it is sent every 96 events, and so on. +::: diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..14f729c5 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,54 @@ +{ + "name": "docs", + "version": "1.0.0", + "private": true, + "type": "module", + "author": "Kurrent Inc", + "devDependencies": { + "@babel/cli": "^7.24.8", + "@babel/core": "^7.24.9", + "@babel/preset-env": "^7.24.8", + "@babel/preset-typescript": "^7.24.7", + "@types/fs-extra": "^11.0.4", + "@types/markdown-it": "^14.1.1", + "degit": "2.8.4", + "del": "5.1.0", + "dotenv": "10.0.0", + "eslint": "^8.57.0", + "eslint-config-vuepress": "^4.10.1", + "eslint-config-vuepress-typescript": "^4.10.1", + "fs-extra": "^11.2.0", + "markdown-it": "^14.1.0", + "prettier": "2.3.2", + "sass": "^1.84.0", + "shx": "0.3.3", + "stylus": "^0.56.0", + "tsconfig-vuepress": "^4.5.0", + "typescript": "^5.5.3", + "vite-plugin-vue-devtools": "^7.3.6", + "@vuepress/plugin-search": "^2.0.0-rc.74", + "@mdit/plugin-dl": "^0.13.0" + }, + "dependencies": { + "@rollup/plugin-alias": "^3.1.9", + "@vuelidate/core": "^2.0.3", + "@vuepress/bundler-vite": "2.0.0-rc.19", + "vuepress-theme-hope": "^2.0.0-rc.71", + "sass-loader": "^15.0.0", + "vue": "^3.4.30", + "vue-router": "^4.4.0", + "vuepress": "2.0.0-rc.19", + "iconify-icon": "^2.1.0", + "mermaid": "^11.3.0" + }, + "scripts": { + "preinstall": "npx only-allow pnpm", + "dev": "vuepress-vite dev .", + "build": "vuepress-vite build .", + "update-package": "pnpm dlx vp-update" + }, + "engines": { + "node": ">=18.19.0" + }, + "packageManager": "pnpm@9.10.0+sha512.73a29afa36a0d092ece5271de5177ecbf8318d454ecd701343131b8ebc0c1a91c487da46ab77c8e596d6acf1461e3594ced4becedf8921b074fbd8653ed7051c" +} diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 00000000..755a706c --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,9767 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@rollup/plugin-alias': + specifier: ^3.1.9 + version: 3.1.9(rollup@4.34.6) + '@vuelidate/core': + specifier: ^2.0.3 + version: 2.0.3(vue@3.4.31(typescript@5.5.3)) + '@vuepress/bundler-vite': + specifier: 2.0.0-rc.19 + version: 2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3) + iconify-icon: + specifier: ^2.1.0 + version: 2.1.0 + mermaid: + specifier: ^11.3.0 + version: 11.3.0 + sass-loader: + specifier: ^15.0.0 + version: 15.0.0(sass@1.84.0) + vue: + specifier: ^3.4.30 + version: 3.4.31(typescript@5.5.3) + vue-router: + specifier: ^4.4.0 + version: 4.4.0(vue@3.4.31(typescript@5.5.3)) + vuepress: + specifier: 2.0.0-rc.19 + version: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + vuepress-theme-hope: + specifier: ^2.0.0-rc.71 + version: 2.0.0-rc.71(@vuepress/plugin-search@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))))(katex@0.16.11)(markdown-it@14.1.0)(mermaid@11.3.0)(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + devDependencies: + '@babel/cli': + specifier: ^7.24.8 + version: 7.24.8(@babel/core@7.25.2) + '@babel/core': + specifier: ^7.24.9 + version: 7.25.2 + '@babel/preset-env': + specifier: ^7.24.8 + version: 7.25.3(@babel/core@7.25.2) + '@babel/preset-typescript': + specifier: ^7.24.7 + version: 7.24.7(@babel/core@7.25.2) + '@mdit/plugin-dl': + specifier: ^0.13.0 + version: 0.13.0(markdown-it@14.1.0) + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/markdown-it': + specifier: ^14.1.1 + version: 14.1.2 + '@vuepress/plugin-search': + specifier: ^2.0.0-rc.74 + version: 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + degit: + specifier: 2.8.4 + version: 2.8.4 + del: + specifier: 5.1.0 + version: 5.1.0 + dotenv: + specifier: 10.0.0 + version: 10.0.0 + eslint: + specifier: ^8.57.0 + version: 8.57.0 + eslint-config-vuepress: + specifier: ^4.10.1 + version: 4.10.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0) + eslint-config-vuepress-typescript: + specifier: ^4.10.1 + version: 4.10.1(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint-plugin-n@16.6.2(eslint@8.57.0))(eslint-plugin-promise@6.4.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.5.3) + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 + markdown-it: + specifier: ^14.1.0 + version: 14.1.0 + prettier: + specifier: 2.3.2 + version: 2.3.2 + sass: + specifier: ^1.84.0 + version: 1.84.0 + shx: + specifier: 0.3.3 + version: 0.3.3 + stylus: + specifier: ^0.56.0 + version: 0.56.0 + tsconfig-vuepress: + specifier: ^4.5.0 + version: 4.5.0 + typescript: + specifier: ^5.5.3 + version: 5.5.3 + vite-plugin-vue-devtools: + specifier: ^7.3.6 + version: 7.3.8(rollup@4.34.6)(vite@6.0.11(sass@1.84.0)(stylus@0.56.0))(vue@3.4.31(typescript@5.5.3)) + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@antfu/install-pkg@0.4.1': + resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@babel/cli@7.24.8': + resolution: {integrity: sha512-isdp+G6DpRyKc+3Gqxy2rjzgF7Zj9K0mzLNnxz+E/fgeag8qT3vVulX4gY9dGO1q0y+0lUv6V3a+uhUzMzrwXg==} + engines: {node: '>=6.9.0'} + hasBin: true + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.2': + resolution: {integrity: sha512-bYcppcpKBvX4znYaPEeFau03bp89ShqNMLs+rmdptMw+heSZh9+z84d2YG+K7cYLbWwzdjtDoW/uqZmPjulClQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.0': + resolution: {integrity: sha512-3LEEcj3PVW8pW2R1SR1M89g/qrYk/m/mB/tLqn7dn4sbBUQyTqnlod+II2U4dqiGtUmkcnAmkMDralTFZttRiw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.24.7': + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': + resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.25.0': + resolution: {integrity: sha512-GYM6BxeQsETc9mnct+nIIpf63SAyzvyYN7UB/IlTyd+MBg06afFGp0mIeUqGyWgS2mxad6vqbMrHVlaL3m70sQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.25.2': + resolution: {integrity: sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.6.2': + resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-member-expression-to-functions@7.24.8': + resolution: {integrity: sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.22.15': + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.24.7': + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.24.8': + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.25.0': + resolution: {integrity: sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.25.0': + resolution: {integrity: sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.24.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.25.0': + resolution: {integrity: sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.0': + resolution: {integrity: sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.25.3': + resolution: {integrity: sha512-iLTJKDbJ4hMvFPgQwwsVoxtHyWpKKPBrxkANrSYewDPaPpT5py5yeVkgPIJ7XYXhndxJpaA3PyALSXQ7u8e/Dw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3': + resolution: {integrity: sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0': + resolution: {integrity: sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0': + resolution: {integrity: sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7': + resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0': + resolution: {integrity: sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-decorators@7.24.7': + resolution: {integrity: sha512-RL9GR0pUG5Kc8BUWLNDm2T5OpYwSX15r98I0IkgmRQTXuELq/OynH8xtMTMvTJFjXbMWFVTKtYkTaYQsuAwQlQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.24.7': + resolution: {integrity: sha512-Ui4uLJJrRV1lb38zg1yYTmRKmiZLiftDEvZN2iq3kd9kUFU+PttmzTbAFC2ucRk/XJmtek6G23gPsuZbhrT8fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-export-namespace-from@7.8.3': + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.24.7': + resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.24.7': + resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.24.7': + resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.25.0': + resolution: {integrity: sha512-uaIi2FdqzjpAMvVqvB51S42oC2JEVgh0LDsGfZVDysWE8LrJtQC2jvKmOqEYThKyB7bDEb7BP1GYWDm7tABA0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.24.7': + resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.24.7': + resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.25.0': + resolution: {integrity: sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.24.7': + resolution: {integrity: sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.24.7': + resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.25.0': + resolution: {integrity: sha512-xyi6qjr/fYU304fiRwFbekzkqVJZ6A7hOjWZd+89FVcBqPV3S9Wuozz82xdpLspckeaafntbzglaW4pqpzvtSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.24.7': + resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.24.8': + resolution: {integrity: sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.24.7': + resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.24.7': + resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0': + resolution: {integrity: sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.24.7': + resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.24.7': + resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.24.7': + resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.24.7': + resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.25.1': + resolution: {integrity: sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.24.7': + resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.25.2': + resolution: {integrity: sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.24.7': + resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.24.7': + resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.24.7': + resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.24.8': + resolution: {integrity: sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.25.0': + resolution: {integrity: sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.24.7': + resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7': + resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.24.7': + resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7': + resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.24.7': + resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.24.7': + resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.24.7': + resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.24.7': + resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.24.8': + resolution: {integrity: sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.24.7': + resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.24.7': + resolution: {integrity: sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.24.7': + resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.24.7': + resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.24.7': + resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-reserved-words@7.24.7': + resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.24.7': + resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.24.7': + resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.24.7': + resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.24.7': + resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.24.8': + resolution: {integrity: sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.25.2': + resolution: {integrity: sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.24.7': + resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.24.7': + resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.24.7': + resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.24.7': + resolution: {integrity: sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.25.3': + resolution: {integrity: sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-typescript@7.24.7': + resolution: {integrity: sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/regjsgen@0.8.0': + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + + '@babel/runtime@7.25.0': + resolution: {integrity: sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.3': + resolution: {integrity: sha512-HefgyP1x754oGCsKmV5reSmtV7IXj/kpaE1XYY+D9G5PvKKoFfSbiS4M77MdjuwlZKDIKFCffq9rPU+H/s3ZdQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.8': + resolution: {integrity: sha512-SkSBEHwwJRU52QEVZBmMBnE5Ux2/6WU1grdYyOhpbCNxbmJrDuDCphBzKZSO3taf0zztp+qkWlymE5tVL5l0TA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.2': + resolution: {integrity: sha512-YTnYtra7W9e6/oAZEHj0bJehPRUlLH9/fbpT5LfB0NhQXyALCRkRs3zH9v07IYhkgpqX6Z78FnuccZr/l4Fs4Q==} + engines: {node: '>=6.9.0'} + + '@braintree/sanitize-url@7.1.0': + resolution: {integrity: sha512-o+UlMLt49RvtCASlOMW0AkHnabN9wR9rwCCherxO0yG4Npy34GkvrAqdXQvrhNs+jh+gkK8gB8Lf05qL/O7KWg==} + + '@chevrotain/cst-dts-gen@11.0.3': + resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} + + '@chevrotain/gast@11.0.3': + resolution: {integrity: sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==} + + '@chevrotain/regexp-to-ast@11.0.3': + resolution: {integrity: sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==} + + '@chevrotain/types@11.0.3': + resolution: {integrity: sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==} + + '@chevrotain/utils@11.0.3': + resolution: {integrity: sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.24.2': + resolution: {integrity: sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.24.2': + resolution: {integrity: sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.24.2': + resolution: {integrity: sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.24.2': + resolution: {integrity: sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.24.2': + resolution: {integrity: sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.24.2': + resolution: {integrity: sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.24.2': + resolution: {integrity: sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.24.2': + resolution: {integrity: sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.24.2': + resolution: {integrity: sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.24.2': + resolution: {integrity: sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.24.2': + resolution: {integrity: sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.24.2': + resolution: {integrity: sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.24.2': + resolution: {integrity: sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.24.2': + resolution: {integrity: sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.24.2': + resolution: {integrity: sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.24.2': + resolution: {integrity: sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.24.2': + resolution: {integrity: sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.24.2': + resolution: {integrity: sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.24.2': + resolution: {integrity: sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.24.2': + resolution: {integrity: sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.24.2': + resolution: {integrity: sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.24.2': + resolution: {integrity: sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.24.2': + resolution: {integrity: sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.24.2': + resolution: {integrity: sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.24.2': + resolution: {integrity: sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.1.33': + resolution: {integrity: sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@lit-labs/ssr-dom-shim@1.2.1': + resolution: {integrity: sha512-wx4aBmgeGvFmOKucFKY+8VFJSYZxs9poN3SDNQFF6lT6NrQUnHiPB2PWz2sc4ieEcAaYYzN+1uWahEeTq2aRIQ==} + + '@lit/reactive-element@2.0.4': + resolution: {integrity: sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==} + + '@mdit-vue/plugin-component@2.1.3': + resolution: {integrity: sha512-9AG17beCgpEw/4ldo/M6Y/1Rh4E1bqMmr/rCkWKmCAxy9tJz3lzY7HQJanyHMJufwsb3WL5Lp7Om/aPcQTZ9SA==} + + '@mdit-vue/plugin-frontmatter@2.1.3': + resolution: {integrity: sha512-KxsSCUVBEmn6sJcchSTiI5v9bWaoRxe68RBYRDGcSEY1GTnfQ5gQPMIsM48P4q1luLEIWurVGGrRu7u93//LDQ==} + + '@mdit-vue/plugin-headers@2.1.3': + resolution: {integrity: sha512-AcL7a7LHQR3ISINhfjGJNE/bHyM0dcl6MYm1Sr//zF7ZgokPGwD/HhD7TzwmrKA9YNYCcO9P3QmF/RN9XyA6CA==} + + '@mdit-vue/plugin-sfc@2.1.3': + resolution: {integrity: sha512-Ezl0dNvQNS639Yl4siXm+cnWtQvlqHrg+u+lnau/OHpj9Xh3LVap/BSQVugKIV37eR13jXXYf3VaAOP1fXPN+w==} + + '@mdit-vue/plugin-title@2.1.3': + resolution: {integrity: sha512-XWVOQoZqczoN97xCDrnQicmXKoqwOjIymIm9HQnRXhHnYKOgJPW1CxSGhkcOGzvDU1v0mD/adojVyyj/s6ggWw==} + + '@mdit-vue/plugin-toc@2.1.3': + resolution: {integrity: sha512-41Q+iXpLHZt0zJdApVwoVt7WF6za/xUjtjEPf90Z3KLzQO01TXsv48Xp9BsrFHPcPcm8tiZ0+O1/ICJO80V/MQ==} + + '@mdit-vue/shared@2.1.3': + resolution: {integrity: sha512-27YI8b0VVZsAlNwaWoaOCWbr4eL8B04HxiYk/y2ktblO/nMcOEOLt4p0RjuobvdyUyjHvGOS09RKhq7qHm1CHQ==} + + '@mdit-vue/types@2.1.0': + resolution: {integrity: sha512-TMBB/BQWVvwtpBdWD75rkZx4ZphQ6MN0O4QB2Bc0oI5PC2uE57QerhNxdRZ7cvBHE2iY2C+BUNUziCfJbjIRRA==} + + '@mdit/helper@0.16.0': + resolution: {integrity: sha512-vUmLSZp+7UXJIYxOya9BkD0OgjgQ+6gpX+htEnc4SKaDPx4S1E7h5TE6Wy4E9Gm/JhkMHoD6TdeoQwrN/I9cLQ==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-alert@0.16.0': + resolution: {integrity: sha512-T+0BUVhKjp+Azp6sNdDbiZwydDIcZP6/NAg9uivPvcsDnI9u4lMRCdXI090xNJOdhHO3l/lOsoO//s+++MJNtA==} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-align@0.16.0': + resolution: {integrity: sha512-BJhOjX4Zobs+ZKEpDtxGrUCnppkFCTGIBLjXkCPmxeLf4Tsh7dqv5vVhbRueSOz/EIzc2RJzR0dlMLofsaCFeA==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-attrs@0.16.7': + resolution: {integrity: sha512-N0zqyuDUO+VeM+vpmVCjujxAbuvE9DhYJoMV9GzLhzmJAP431JMsBBs/sRrJG9tvZrVFZbUMuq4uZz2CHAdkxQ==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-container@0.16.0': + resolution: {integrity: sha512-NCsyEiOmoJvXSEVJSY6vaEcvbE11sciRSx5qXBvQQZxUYGYsB+ObYSFVZDFPezsEN35X3b07rurLx8P2Mi9DgQ==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-demo@0.16.0': + resolution: {integrity: sha512-EoSpHz8ViLk5HLBCSzQZGOa36JXGHM4q5zOJ0ppgZymxnzRr6vUo+GX022uLivxyNMW1+l30IiF+jbse+JtBGw==} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-dl@0.13.0': + resolution: {integrity: sha512-6IC+82oDrXqxQ0Tg6ifTw70HoFk5hI/e9qQgmH5PAu8igTSWLOCSV1RfQc3bYEBKoSZGYnrjs/PtgJHgRLSgZQ==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-figure@0.16.0': + resolution: {integrity: sha512-0lYZX3cCUNaygtQXXZH2fHXzmF7sMZ5Jbk5MXDxEDIk1Nkxj8ADo/SctvXN5exwyGpJyw8nTbm7CGgMqifDpmQ==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-footnote@0.16.0': + resolution: {integrity: sha512-vaJWhOsya7bYfplLlMHYBxGTbME0e46/eTVKBROemWtAf873DTkV4IhkAq7MzGqeYrw0L9gxQPgGDFphGfySMA==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + + '@mdit/plugin-icon@0.16.5': + resolution: {integrity: sha512-9T34gnNrjCMdqNLnC1oi+kZT1iCnwlHAtH3D7sjVkcP8Cw4GoDoAGy50oyryivDlczrKubOFtF05lYAfXZauuA==} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-img-lazyload@0.16.0': + resolution: {integrity: sha512-Ilf3e5SKG7hd+RAoYQalpjoz8LMCxCe3BBHFYerv8u4wLnKe/L0Gqc8kXSpR37flzv3Ncw/NMqmD4ZZ0QQnK9A==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-img-mark@0.16.0': + resolution: {integrity: sha512-BUYqQRWUxNKB0BbMb8SZtlTeDZNXxuJ9AuiuB54RIWlbx3iRlQkbQI3B/AxTT5/EbRMDhxOq0R8PumBuA1gNFA==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-img-size@0.16.0': + resolution: {integrity: sha512-4FBvIHYWT22bjU+kO1I00xLtnCi7aXdZ7QD3CJnK4Xl6gN8/WB9IkfqYnBPv8yDiaZrabduQo8Dh8Dm8hPOm2A==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-include@0.16.0': + resolution: {integrity: sha512-9ESwsc+/jYkS0hIzpWqMQ9bHgHG//35datnfp0KUOql/DSuLVhufPtNkKNe/SVNO/+AOBTTlRYzej9Jl7JjD7g==} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-katex-slim@0.16.7': + resolution: {integrity: sha512-pHaaz0WVhBepyKLRNtk1GyZU+kf3oQ7qWoESOoLBEOkOakZJuVVT4oNfrFgbfW2obW983q3z9l4kHjMRx/bn5g==} + engines: {node: '>= 18'} + peerDependencies: + katex: ^0.16.9 + markdown-it: ^14.1.0 + peerDependenciesMeta: + katex: + optional: true + markdown-it: + optional: true + + '@mdit/plugin-mark@0.16.0': + resolution: {integrity: sha512-VY8HhLaNw6iO6E1pSZr3bG6MzyxcAdQmQ+S0r/l87S0EKHCBrUJusaUjxa9aTVHiBcgGUjg9aumribGrWfuitA==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-mathjax-slim@0.16.0': + resolution: {integrity: sha512-bbo6HtNOFdNMGZH/pxc3X1vZOvOW1FF9RMiAW2pkmyk7sPnMziB8uwxm0Ra1RajEC/NDxJ3wcF7xynkLmS6PfA==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + mathjax-full: ^3.2.2 + peerDependenciesMeta: + markdown-it: + optional: true + mathjax-full: + optional: true + + '@mdit/plugin-plantuml@0.16.0': + resolution: {integrity: sha512-ZjGOWYxPcGFq/TAJ2wOU6vCYH82685ERFQAC+xUsd/f6G41oGmk5i2aNqfNYYPmoQvcPvimGUPky9L6k2IXKXw==} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-spoiler@0.16.0': + resolution: {integrity: sha512-lm2lLx5H6649igzmbEe7KGsYfS6EOHn3Ps1ZdOHIFo0AY9eEh//gbjPOuJNJU58vtMnzLYzQHQKp/JqViYTIQQ==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-stylize@0.16.0': + resolution: {integrity: sha512-uxM9aFdgS5YCXOSNSdYyC+uXyCnmqv1VUPRNAv0g/iOts0pUp63ZEUEO2sNlbXj1rGGEWylXyXqh3OU9rRngzg==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-sub@0.16.0': + resolution: {integrity: sha512-XpGcZW11SAWuiWtx9aYugM67OLtQJSfN87Q/aZbEfm6ahgdbO5lAe/vBFTBmL9aDc2EVatytGeZL3kA7pfHlOA==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-sup@0.16.0': + resolution: {integrity: sha512-45Sws9TC9h9ZRB/IcXAae+uYXb+FkVr/rkr9eMYKMFKksjMBddN+WY3Gpl9O7LhaGPipqTkm68QZnRSS1jvFkw==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-tab@0.16.0': + resolution: {integrity: sha512-c+/oT319DIWaMHyx5chueW8cy4pjC7E09QOg3qp86abTCdG2ljGLOlMAQbst5i/iH684QG/i8EJpB4oUeQdhkw==} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-tasklist@0.16.0': + resolution: {integrity: sha512-pxVxartDd8LYxhdYxyrh4c7JEAq+4cEMLI1HNCHTMK9cfO+SoVd/YpibfrDUg+LHvffc8Pf2Yc8pWXNoW34B1g==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-tex@0.16.0': + resolution: {integrity: sha512-VWb5rJYP0eBRRjYhcaRE3r8UQkUaBXzu0l42ck7DOp+MSPsgXfS+bmk8/tyHG6/X/Mig9H92Lh1jzTqp3f5yKg==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mdit/plugin-uml@0.16.0': + resolution: {integrity: sha512-BIsq6PpmRgoThtVR2j4BGiRGis6jrcxxqQW3RICacrG52Ps2RWEGwu7B/IvXs+KJZJLJsrKFQ2Pqaxttbjx3kw==} + engines: {node: '>= 18'} + peerDependencies: + markdown-it: ^14.1.0 + peerDependenciesMeta: + markdown-it: + optional: true + + '@mermaid-js/parser@0.3.0': + resolution: {integrity: sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==} + + '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': + resolution: {integrity: sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@parcel/watcher-android-arm64@2.5.1': + resolution: {integrity: sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.1': + resolution: {integrity: sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.1': + resolution: {integrity: sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.1': + resolution: {integrity: sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.1': + resolution: {integrity: sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm-musl@2.5.1': + resolution: {integrity: sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + resolution: {integrity: sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-arm64-musl@2.5.1': + resolution: {integrity: sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + + '@parcel/watcher-linux-x64-glibc@2.5.1': + resolution: {integrity: sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-linux-x64-musl@2.5.1': + resolution: {integrity: sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + + '@parcel/watcher-win32-arm64@2.5.1': + resolution: {integrity: sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.1': + resolution: {integrity: sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.1': + resolution: {integrity: sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.1': + resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} + engines: {node: '>= 10.0.0'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@polka/url@1.0.0-next.25': + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + + '@rollup/plugin-alias@3.1.9': + resolution: {integrity: sha512-QI5fsEvm9bDzt32k39wpOwZhVzRcL5ydcffUHMyLVaVaLeC70I8TJZ17F1z1eMoLu4E/UOcH9BWVkKpIKdrfiw==} + engines: {node: '>=8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.34.6': + resolution: {integrity: sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.34.6': + resolution: {integrity: sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.34.6': + resolution: {integrity: sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.34.6': + resolution: {integrity: sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.34.6': + resolution: {integrity: sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.34.6': + resolution: {integrity: sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.34.6': + resolution: {integrity: sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.34.6': + resolution: {integrity: sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.34.6': + resolution: {integrity: sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.34.6': + resolution: {integrity: sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.34.6': + resolution: {integrity: sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.34.6': + resolution: {integrity: sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.34.6': + resolution: {integrity: sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.34.6': + resolution: {integrity: sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.34.6': + resolution: {integrity: sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.34.6': + resolution: {integrity: sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.34.6': + resolution: {integrity: sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.34.6': + resolution: {integrity: sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.34.6': + resolution: {integrity: sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==} + cpu: [x64] + os: [win32] + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@shikijs/core@2.3.2': + resolution: {integrity: sha512-s7vyL3LzUKm3Qwf36zRWlavX9BQMZTIq9B1almM63M5xBuSldnsTHCmsXzoF/Kyw4k7Xgas7yAyJz9VR/vcP1A==} + + '@shikijs/engine-javascript@2.3.2': + resolution: {integrity: sha512-w3IEMu5HfL/OaJTsMbIfZ1HRPnWVYRANeDtmsdIIEgUOcLjzFJFQwlnkckGjKHekEzNqlMLbgB/twnfZ/EEAGg==} + + '@shikijs/engine-oniguruma@2.3.2': + resolution: {integrity: sha512-vikMY1TroyZXUHIXbMnvY/mjtOxMn+tavcfAeQPgWS9FHcgFSUoEtywF5B5sOLb9NXb8P2vb7odkh3nj15/00A==} + + '@shikijs/langs@2.3.2': + resolution: {integrity: sha512-UqI6bSxFzhexIJficZLKeB1L2Sc3xoNiAV0yHpfbg5meck93du+EKQtsGbBv66Ki53XZPhnR/kYkOr85elIuFw==} + + '@shikijs/themes@2.3.2': + resolution: {integrity: sha512-QAh7D/hhfYKHibkG2tti8vxNt3ekAH5EqkXJeJbTh7FGvTCWEI7BHqNCtMdjFvZ0vav5nvUgdvA7/HI7pfsB4w==} + + '@shikijs/transformers@2.3.2': + resolution: {integrity: sha512-2HDnJumw8A/9GecRpTgvfqSbPjEbJ4DPWq5J++OVP1gNMLvbV0MqFsP4canqRNM1LqB7VmWY45Stipb0ZIJ+0A==} + + '@shikijs/types@2.3.2': + resolution: {integrity: sha512-CBaMY+a3pepyC4SETi7+bSzO0f6hxEQJUUuS4uD7zppzjmrN4ZRtBqxaT+wOan26CR9eeJ5iBhc4qvWEwn7Eeg==} + + '@shikijs/vscode-textmate@10.0.1': + resolution: {integrity: sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==} + + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@stackblitz/sdk@1.11.0': + resolution: {integrity: sha512-DFQGANNkEZRzFk1/rDP6TcFdM82ycHE+zfl9C/M/jXlH68jiqHWHFMQURLELoD8koxvu/eW5uhg94NSAZlYrUQ==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/hash-sum@1.0.2': + resolution: {integrity: sha512-UP28RddqY8xcU0SCEp9YKutQICXpaAq9N8U2klqF5hegGha7KzTOL8EdhIIV3bOSGBzjEpN9bU/d+nNZBdJYVw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it-emoji@3.0.1': + resolution: {integrity: sha512-cz1j8R35XivBqq9mwnsrP2fsz2yicLhB8+PDtuVkKOExwEdsVBNI+ROL3sbhtR5occRZ66vT0QnwFZCqdjf3pA==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + + '@types/ms@0.7.31': + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + + '@types/node@17.0.45': + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + + '@types/sax@1.2.7': + resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@typescript-eslint/eslint-plugin@7.16.0': + resolution: {integrity: sha512-py1miT6iQpJcs1BiJjm54AMzeuMPBSPuKPlnT8HlfudbcS5rYeX5jajpLf3mrdRh9dA/Ec2FVUY0ifeVNDIhZw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.16.0': + resolution: {integrity: sha512-ar9E+k7CU8rWi2e5ErzQiC93KKEFAXA2Kky0scAlPcxYblLt8+XZuHUZwlyfXILyQa95P6lQg+eZgh/dDs3+Vw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.16.0': + resolution: {integrity: sha512-8gVv3kW6n01Q6TrI1cmTZ9YMFi3ucDT7i7aI5lEikk2ebk1AEjrwX8MDTdaX5D7fPXMBLvnsaa0IFTAu+jcfOw==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.16.0': + resolution: {integrity: sha512-j0fuUswUjDHfqV/UdW6mLtOQQseORqfdmoBNDFOqs9rvNVR2e+cmu6zJu/Ku4SDuqiJko6YnhwcL8x45r8Oqxg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.16.0': + resolution: {integrity: sha512-fecuH15Y+TzlUutvUl9Cc2XJxqdLr7+93SQIbcZfd4XRGGKoxyljK27b+kxKamjRkU7FYC6RrbSCg0ALcZn/xw==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.16.0': + resolution: {integrity: sha512-a5NTvk51ZndFuOLCh5OaJBELYc2O3Zqxfl3Js78VFE1zE46J2AaVuW+rEbVkQznjkmlzWsUI15BG5tQMixzZLw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.16.0': + resolution: {integrity: sha512-PqP4kP3hb4r7Jav+NiRCntlVzhxBNWq6ZQ+zQwII1y/G/1gdIPeYDCKr2+dH6049yJQsWZiHU6RlwvIFBXXGNA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.16.0': + resolution: {integrity: sha512-rMo01uPy9C7XxG7AFsxa8zLnWXTF8N3PYclekWSrurvhwiw1eW88mrKiAYe6s53AUY57nTRz8dJsuuXdkAhzCg==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vitejs/plugin-vue@5.2.1': + resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@vue/babel-helper-vue-transform-on@1.2.2': + resolution: {integrity: sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw==} + + '@vue/babel-plugin-jsx@1.2.2': + resolution: {integrity: sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.2.2': + resolution: {integrity: sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.4.31': + resolution: {integrity: sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==} + + '@vue/compiler-core@3.4.38': + resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==} + + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.4.31': + resolution: {integrity: sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==} + + '@vue/compiler-dom@3.4.38': + resolution: {integrity: sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-sfc@3.4.31': + resolution: {integrity: sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==} + + '@vue/compiler-sfc@3.4.38': + resolution: {integrity: sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==} + + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + + '@vue/compiler-ssr@3.4.31': + resolution: {integrity: sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==} + + '@vue/compiler-ssr@3.4.38': + resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} + + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + + '@vue/devtools-api@6.6.3': + resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/devtools-api@7.7.2': + resolution: {integrity: sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==} + + '@vue/devtools-core@7.3.8': + resolution: {integrity: sha512-mEwsR7GMklWuPOBH/++DiJe0GWqQ0syDtWP0HhU8m9tebs5zQtujMXrgu+cgBAKquJAWnBz0PwNzBgBD2P+M9A==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-kit@7.3.8': + resolution: {integrity: sha512-HYy3MQP1nZ6GbE4vrgJ/UB+MvZnhYmEwCa/UafrEpdpwa+jNCkz1ZdUrC5I7LpkH1ShREEV2/pZlAQdBj+ncLQ==} + + '@vue/devtools-kit@7.7.2': + resolution: {integrity: sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==} + + '@vue/devtools-shared@7.3.8': + resolution: {integrity: sha512-1NiJbn7Yp47nPDWhFZyEKpB2+5/+7JYv8IQnU0ccMrgslPR2dL7u1DIyI7mLqy4HN1ll36gQy0k8GqBYSFgZJw==} + + '@vue/devtools-shared@7.7.2': + resolution: {integrity: sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==} + + '@vue/reactivity@3.4.31': + resolution: {integrity: sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==} + + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + + '@vue/runtime-core@3.4.31': + resolution: {integrity: sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==} + + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + + '@vue/runtime-dom@3.4.31': + resolution: {integrity: sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==} + + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + + '@vue/server-renderer@3.4.31': + resolution: {integrity: sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==} + peerDependencies: + vue: 3.4.31 + + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + peerDependencies: + vue: 3.5.13 + + '@vue/shared@3.4.31': + resolution: {integrity: sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==} + + '@vue/shared@3.4.38': + resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + + '@vuelidate/core@2.0.3': + resolution: {integrity: sha512-AN6l7KF7+mEfyWG0doT96z+47ljwPpZfi9/JrNMkOGLFv27XVZvKzRLXlmDPQjPl/wOB1GNnHuc54jlCLRNqGA==} + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^2.0.0 || >=3.0.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + '@vuepress/bundler-vite@2.0.0-rc.19': + resolution: {integrity: sha512-Vn0wEVRcdAld+8NJeELSwrj5JEPObRn0xpRWtAau/UwVWHmMLo16RRkTvXdjSiwpDWeP/9ztC5buyTXVoeb7Dw==} + + '@vuepress/bundlerutils@2.0.0-rc.19': + resolution: {integrity: sha512-ln5htptK14OMJV3yeGRxAwYhSkVxrTwEHEaifeWrFvjuNxj2kLmkCl7MDdzr232jSOWwkCcmbOyafbxMsaRDkQ==} + + '@vuepress/cli@2.0.0-rc.19': + resolution: {integrity: sha512-QFicPNIj3RZAJbHoLbeYlPJsPchnQLGuw0n8xv0eeUi9ejEXO1huWA8sLoPbTGdiDW+PHr1MHnaVMkyUfwaKcQ==} + hasBin: true + + '@vuepress/client@2.0.0-rc.19': + resolution: {integrity: sha512-vUAU6n4qmtXqthxkb4LHq0D+VWSDenwBDf0jUs7RaBLuOVrbPtmH/hs4k1vLIlGdwC3Zs/G6tlB4UmuZiiwR8Q==} + + '@vuepress/core@2.0.0-rc.19': + resolution: {integrity: sha512-rvmBPMIWS2dey/2QjxZoO0OcrUU46NE3mSLk3oU7JOP0cG7xvRxf6U1OXiwYLC3fPO4g6XbHiKe6gihkmL6VDA==} + + '@vuepress/helper@2.0.0-rc.74': + resolution: {integrity: sha512-k0FjkM9TKggcWkyZwXj4cLUIF3FBJ5iZGnC+Ln4OJVGD7k3SvT7TL7IaCZoFBIXTlepZwytsIN7K5Lbmpx0GfQ==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/highlighter-helper@2.0.0-rc.71': + resolution: {integrity: sha512-Hi9ira4VmX1MuRcagbSIZ/hHtwB4Fduz/NfiFGmOYX68zWIsQ1e90Ntku8GeI2MEDWlFxGU8PY/7VcXwINjoXQ==} + peerDependencies: + '@vueuse/core': ^12.2.0 + vuepress: 2.0.0-rc.19 + peerDependenciesMeta: + '@vueuse/core': + optional: true + + '@vuepress/markdown@2.0.0-rc.19': + resolution: {integrity: sha512-6jgUXhpEK55PEEGtPhz7Hq/JqTbLU8n9w2D7emXiK2FYcbeKpjoRIbVRzmzB/dXeK3NzHChANu2IIqpOT6Ba1w==} + + '@vuepress/plugin-active-header-links@2.0.0-rc.74': + resolution: {integrity: sha512-ErXPpq52hKS0AubppT8HOqST5BBr2ibMK8LF2ctmoS7fZr8VlRysVn6jpLRGdDG+hBIHqbHsitBwMp5y1k99ag==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-back-to-top@2.0.0-rc.74': + resolution: {integrity: sha512-/r7pUarK67s3ZedfoUQ7JxcOcrSTxcSMiu6ozQW5vfe7s3d2WzIeaW/dsXPlmAdCEU0MZcb5RXRCNHBdZ9Zo2Q==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-blog@2.0.0-rc.74': + resolution: {integrity: sha512-CxVrkwLT3BHkwWaEyaaqeZ5YZ9kdqLaNjTidw9zMK0LAFCm62MrCUrhJnUeSEy233Gi3YYSiCV8hPRnUDMMa7A==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-catalog@2.0.0-rc.74': + resolution: {integrity: sha512-Oqz5BXVVdGfGlfTg+wxwUn5RFCPIVkLykBejMJy6E5oLeQC7Ofp9tg9KJze6nPoknXJWY78MEwRq0UQIC9oX9g==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-comment@2.0.0-rc.74': + resolution: {integrity: sha512-pBDe4Ua5UOme3C4FWW1ZCXiTMGjOL5YppOtwexmrPxFMZ3G5OpN2Eli5AHQjsl2lQADtDwciKuVFspTpNWbdFw==} + peerDependencies: + '@waline/client': ^3.5.0 + artalk: ^2.9.0 + twikoo: ^1.6.39 + vuepress: 2.0.0-rc.19 + peerDependenciesMeta: + '@waline/client': + optional: true + artalk: + optional: true + twikoo: + optional: true + + '@vuepress/plugin-copy-code@2.0.0-rc.74': + resolution: {integrity: sha512-flyUj8Xwj0G2jKMTtTrdJGpMS4By90kJGgEbxDTobV4t/98hpBBvEiL1AQ8oGIcQFHH6U+eNRPytde6/7NxKlw==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-copyright@2.0.0-rc.74': + resolution: {integrity: sha512-T0KM753aiJsfXPgWSRIdKHit4CB9pNDCXcz1xRBMKRtI2WdajWPHpF7clrmgIwmZzvgNhxz5DtW80vDbyp0G0A==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-git@2.0.0-rc.68': + resolution: {integrity: sha512-k/tXBSIyQM26UrmDK/mN1/q6gw8PmF2uLyIaso+B39qCOFQKUBq4uJF2a0oYTq9tpjM5AHwwBpytPE5cdV/BPQ==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-icon@2.0.0-rc.74': + resolution: {integrity: sha512-JwodDsB5jQuoqFEW7cAWNyJG1GyiEaHiaLphIPjZZaO+QIt5wgRakhydd8VK/PqICzav/WO8LknN/i6OqhpUYw==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-links-check@2.0.0-rc.74': + resolution: {integrity: sha512-/g+mosEv2iqbTVD7QpPIP0f0OGC8cQEO6VZgwxj25Swcnq0ndsuq0NOO+SIRasdYZe2xTZ94eNXcZEcKlCA9uw==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-markdown-ext@2.0.0-rc.74': + resolution: {integrity: sha512-+SrSu95GKoGSCvIG1EAMctF7YKbbPAc3phbz0DuywuJjhEo7dC8T74tYGwj+AG8BFTVPFr3rMJTssdpHiUogNw==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-markdown-hint@2.0.0-rc.74': + resolution: {integrity: sha512-1vC11eie+85XoIxQNWFgevpkYCcnc3DMi+x7WAc89+7yk0gP7zJVolWaPH1lLNfmoMxmpfms5ssEnUpr3vHMEQ==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-markdown-image@2.0.0-rc.74': + resolution: {integrity: sha512-x0j3FNBoexTRurgy0ycPnW8na4FR5pJC1n/vAInqu5w6U2O7PANr7tgKUz2r+XXfRpNh3j5JyLKWmJLvHdu8UA==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-markdown-include@2.0.0-rc.74': + resolution: {integrity: sha512-yLoWBhlOoWLQrMD30hFKquNt7IZvQiW45O5unztEy2F9bI1MicyBxUnbSMe8d+HNkuAaKxIeDqyt5pVFbqLb0w==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-markdown-math@2.0.0-rc.74': + resolution: {integrity: sha512-C0rG1A1I3fxrQ1VQtNepnoPuUnnjtNd9lFaW8WeEIKuLQVt2jWKjPXK6yMeu/0OwtyYYPZ5PJmofn0mFLbOZTw==} + peerDependencies: + katex: ^0.16.10 + mathjax-full: ^3.2.2 + vuepress: 2.0.0-rc.19 + peerDependenciesMeta: + katex: + optional: true + mathjax-full: + optional: true + + '@vuepress/plugin-markdown-stylize@2.0.0-rc.75': + resolution: {integrity: sha512-ratBXmz4TeOANsjyC4/F0K3kUe0YpFF8+OoPmX6GqqnVnk0UAM50BALYy+ca1R2imC0HRXSWp2jEmsKRCTt6OQ==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-markdown-tab@2.0.0-rc.74': + resolution: {integrity: sha512-LhsOEVDfOLpyjBKwx9ZsMbWD8NVQkHgjT+AbZMd2f+fnOaTw7cvWtJxTsg6yQZt2c0Wc3268WtaqxeuqaHTZ6w==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-notice@2.0.0-rc.74': + resolution: {integrity: sha512-6cVP7x5zDup+65tjkRnZhBy3tHXhN7pNcBcACKrLE/G3p1rb6SZiSoNk1H2Iva0RAFARzP1fztgTgasLWurofg==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-nprogress@2.0.0-rc.74': + resolution: {integrity: sha512-tgbMm2+MwJaUzqTBioeXYs8gaPXS9gYbvTg6HpFU0B4dJJ3CBq62CZEuord6T3Q6m/PnZz1H98bb3BmosKg1OA==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-photo-swipe@2.0.0-rc.74': + resolution: {integrity: sha512-yeFIXmlzefQOrKBFWKN4KYi8YM8rKRMD2M/L1hqtPp1rBudhfOva4c6ZKqgYnTyf7A1KlZRer1QCUQ3GWdRxew==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-reading-time@2.0.0-rc.74': + resolution: {integrity: sha512-VK7hwq077eiZ4igVLzX01Dioxy40DXqCSgNHtoycfrsQjqBuxyokVEQHe2+q0jvGLBXcrt381x/ZCDsUwVZhDw==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-redirect@2.0.0-rc.74': + resolution: {integrity: sha512-zSfwcKD25MBGC2BZ/VD6XxJtpgDeUoAbZvkn3kuhakYllUHz94cFmxgbu+RukwL78Nam/UFj6ukyh4YCH3mMgg==} + hasBin: true + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-rtl@2.0.0-rc.74': + resolution: {integrity: sha512-T77zrw5htxe3uwjgqPKN1iU2zQlPnXl/YrQPVqIWEJJ4uNt93ZLyU892SiGWXNFMmqn8wes9PziCzBEAXqlKkQ==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-sass-palette@2.0.0-rc.74': + resolution: {integrity: sha512-bNXw/mMQrgRhhWGKx/W+agFORLbR33Z6FyNbGk6u7ZCSkuKlMcu8A5H+GLl4Jr0uvTTF6UESAxsJZVtRGZcTSQ==} + peerDependencies: + sass: ^1.80.3 + sass-embedded: ^1.80.3 + sass-loader: ^16.0.2 + vuepress: 2.0.0-rc.19 + peerDependenciesMeta: + sass: + optional: true + sass-embedded: + optional: true + sass-loader: + optional: true + + '@vuepress/plugin-search@2.0.0-rc.74': + resolution: {integrity: sha512-zDSl/vLRjtQIT8a8jZJ/fFQyJYZMSqcFJFUqpOWojNgDiTNZwa83PJxl0Tq8YdfSgmi4odwTl06xzpAuY6Pi3g==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-seo@2.0.0-rc.74': + resolution: {integrity: sha512-Z5Q35Y3TALhfhOs8DocBtQcyRCp0/Btjec7DfnDih5p5rhRI7dHI7DIdf9aJHTuz1VxpzCfru6sApqSdbPlc5g==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-shiki@2.0.0-rc.74': + resolution: {integrity: sha512-75wMcxa18JhFdTpGPzCeKJl0bc6gZ/ODKRbJo7wRRNLo3UOFBAcqTER3az2hi5b1xVUKrLWkbULSGivfeyvPSw==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-sitemap@2.0.0-rc.74': + resolution: {integrity: sha512-Kbr9u3fryw34s9ZdxY4fKsCQcN74aFal34CJ4xPxx5E6liE9Rp+gOWevOl89qYXfXgPfyHHJlW5KYfonaZe9Sw==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/plugin-theme-data@2.0.0-rc.74': + resolution: {integrity: sha512-6uQPv4kRakqcEPWmL3ZYKqjXqzOVycAdlr7oQlxs23E8CO59/QyIcrkloHPsdI+VhAA3v46NdiVD2TIrESRm6A==} + peerDependencies: + vuepress: 2.0.0-rc.19 + + '@vuepress/shared@2.0.0-rc.19': + resolution: {integrity: sha512-xaDeZxX0Qetc2Y6/lrzO6M/40i3LmMm7Fk85bOftBBOaNehZ24RdsmIHBJDDv+bTUv+DBF++1/mOtbt6DBRzEA==} + + '@vuepress/utils@2.0.0-rc.19': + resolution: {integrity: sha512-cgzk8/aJquZKgFMNTuqdjbU5NrCzrPmdTyhYBcmliL/6N/He1OTWn3PD9QWUGJNODb1sPRJpklZnCpU07waLmg==} + + '@vueuse/core@12.5.0': + resolution: {integrity: sha512-GVyH1iYqNANwcahAx8JBm6awaNgvR/SwZ1fjr10b8l1HIgDp82ngNbfzJUgOgWEoxjL+URAggnlilAEXwCOZtg==} + + '@vueuse/metadata@12.5.0': + resolution: {integrity: sha512-Ui7Lo2a7AxrMAXRF+fAp9QsXuwTeeZ8fIB9wsLHqzq9MQk+2gMYE2IGJW48VMJ8ecvCB3z3GsGLKLbSasQ5Qlg==} + + '@vueuse/shared@12.5.0': + resolution: {integrity: sha512-vMpcL1lStUU6O+kdj6YdHDixh0odjPAUM15uJ9f7MY781jcYkIwFA4iv2EfoIPO6vBmvutI1HxxAwmf0cx5ISQ==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + autoprefixer@10.4.20: + resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + babel-plugin-polyfill-corejs2@0.4.11: + resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.10.6: + resolution: {integrity: sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.2: + resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balloon-css@1.2.0: + resolution: {integrity: sha512-urXwkHgwp6GsXVF+it01485Z2Cj4pnW02ICnM0TemOlkKmCNnDLmyy+ZZiRXBpwldUXO+aRNr7Hdia4CBvXJ5A==} + + bcrypt-ts@5.0.3: + resolution: {integrity: sha512-2FcgD12xPbwCoe5i9/HK0jJ1xA1m+QfC1e6htG9Bl/hNOnLyaFmQSlqLKcfe3QdnoMPKpKEGFCbESBTg+SJNOw==} + engines: {node: '>=18'} + + binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + + birpc@0.2.17: + resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==} + + birpc@0.2.19: + resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.23.2: + resolution: {integrity: sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + builtins@5.1.0: + resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001641: + resolution: {integrity: sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==} + + caniuse-lite@1.0.30001651: + resolution: {integrity: sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0: + resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} + engines: {node: '>=18.17'} + + chevrotain-allstar@0.3.1: + resolution: {integrity: sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==} + peerDependencies: + chevrotain: ^11.0.0 + + chevrotain@11.0.3: + resolution: {integrity: sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + core-js-compat@3.38.0: + resolution: {integrity: sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A==} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cose-base@2.2.0: + resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + + create-codepen@2.0.0: + resolution: {integrity: sha512-ehJ0Zw5RSV2G4+/azUb7vEZWRSA/K9cW7HDock1Y9ViDexkgSJUZJRcObdw/YAWeXKjreEQV9l/igNSsJ1yw5A==} + engines: {node: '>=18'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + css@3.0.0: + resolution: {integrity: sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape-fcose@2.2.0: + resolution: {integrity: sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.30.3: + resolution: {integrity: sha512-HncJ9gGJbVtw7YXtIs3+6YAFSSiKsom0amWc33Z7QbylbY2JGMrA0yz4EwrdTScZxnwclXeEZHzO5pxoy0ZE4g==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + dagre-d3-es@7.0.10: + resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + dayjs@1.11.12: + resolution: {integrity: sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + degit@2.8.4: + resolution: {integrity: sha512-vqYuzmSA5I50J882jd+AbAhQtgK6bdKUJIex1JNfEUPENCgYsxugzKVZlFyMwV4i06MmnV47/Iqi5Io86zf3Ng==} + engines: {node: '>=8.0.0'} + hasBin: true + + del@5.1.0: + resolution: {integrity: sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==} + engines: {node: '>=8'} + + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + dompurify@3.1.6: + resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dotenv@10.0.0: + resolution: {integrity: sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==} + engines: {node: '>=10'} + + electron-to-chromium@1.4.825: + resolution: {integrity: sha512-OCcF+LwdgFGcsYPYC5keEEFC2XT0gBhrYbeGzHCx7i9qRFbzO/AqTmc/C/1xNhJj+JA7rzlN7mpBuStshh96Cg==} + + electron-to-chromium@1.5.9: + resolution: {integrity: sha512-HfkT8ndXR0SEkU8gBQQM3rz035bpE/hxkZ1YIt4KJPEFES68HfIU6LzKukH0H794Lm83WJtkSAMfEToxCs15VA==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} + + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encoding-sniffer@0.2.0: + resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + envinfo@7.14.0: + resolution: {integrity: sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==} + engines: {node: '>=4'} + hasBin: true + + error-stack-parser-es@0.1.5: + resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.24.2: + resolution: {integrity: sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-config-standard@17.1.0: + resolution: {integrity: sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + eslint: ^8.0.1 + eslint-plugin-import: ^2.25.2 + eslint-plugin-n: '^15.0.0 || ^16.0.0 ' + eslint-plugin-promise: ^6.0.0 + + eslint-config-vuepress-typescript@4.10.1: + resolution: {integrity: sha512-MD6Z0K/GViVIIRuCym2CfHb8XB2JJ3MXPN5gNe+Bv2lAXOyi5/IUDR+BjBjA/Hdo6xrLHQOM+I8gtQrxUuddjg==} + + eslint-config-vuepress@4.10.1: + resolution: {integrity: sha512-VunYtLhFdDxReGRCp+Lba86f18Hd/Srb+tOVbonYFITUNtpr8y85JgtVrXCS9c5+JE9PPx0JcxAFDxWDtoTH7g==} + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-module-utils@2.8.1: + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-es-x@7.8.0: + resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-import@2.29.1: + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-n@16.6.2: + resolution: {integrity: sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-promise@6.4.0: + resolution: {integrity: sha512-/KWWRaD3fGkVCZsdR0RU53PSthFmoHVhZl+y9+6DqeDLSikLdlUVpVEAmI6iCRR5QyOjBYBqHZV/bdv4DJ4Gtw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-vue@9.27.0: + resolution: {integrity: sha512-5Dw3yxEyuBSXTzT5/Ge1X5kIkRTQ3nvBn/VwPwInNiZBSJOO/timWMUaflONnFBzU6NhB68lxnCda7ULV5N7LA==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.5.2: + resolution: {integrity: sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==} + engines: {node: ^18.19.0 || >=20.5.0} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + fraction.js@4.3.7: + resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + giscus@1.6.0: + resolution: {integrity: sha512-Zrsi8r4t1LVW950keaWcsURuZUQwUaMKjvJgTCY125vkW6OiEBkatE7ScJDbpqKHdZwb///7FVC21SE3iFK3PQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@10.0.2: + resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@14.0.2: + resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} + engines: {node: '>=18'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + + hachure-fill@0.5.2: + resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hash-sum@2.0.0: + resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hast-util-to-html@9.0.4: + resolution: {integrity: sha512-wxQzXtdbhiwGAUKrnQJXlOPmHnEehzphwkK7aluUPQ+lEc1xefC8pblMgpp2w5ldBTEfveRIrADcrhGIWrlTDA==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + htmlparser2@9.1.0: + resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@8.0.0: + resolution: {integrity: sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==} + engines: {node: '>=18.18.0'} + + iconify-icon@2.1.0: + resolution: {integrity: sha512-lto4XU3bwTQnb+D/CsJ4dWAo0aDe+uPMxEtxyOodw9l7R9QnJUUab3GCehlw2M8mDHdeUu/ufx8PvRQiJphhXg==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + immutable@5.0.3: + resolution: {integrity: sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.14.0: + resolution: {integrity: sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + katex@0.16.11: + resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + langium@3.0.0: + resolution: {integrity: sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==} + engines: {node: '>=16.0.0'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + layout-base@2.0.1: + resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.2: + resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==} + engines: {node: '>=14'} + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + lit-element@4.1.0: + resolution: {integrity: sha512-gSejRUQJuMQjV2Z59KAS/D4iElUhwKpIyJvZ9w+DIagIQjfJnhR20h2Q5ddpzXGS+fF0tMZ/xEYGMnKmaI/iww==} + + lit-html@3.2.0: + resolution: {integrity: sha512-pwT/HwoxqI9FggTrYVarkBKFN9MlTUpLrDHubTmW4SrkL3kkqW5gxwbxMMUnbbRHBC0WTZnYHcjDSCM559VyfA==} + + lit@3.2.1: + resolution: {integrity: sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + markdown-it-anchor@9.2.0: + resolution: {integrity: sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==} + peerDependencies: + '@types/markdown-it': '*' + markdown-it: '*' + + markdown-it-emoji@3.0.0: + resolution: {integrity: sha512-+rUD93bXHubA4arpEZO3q80so0qgoFJEKRkRbjKX8RTdca89v2kfyF+xR3i2sQTwql9tpPZPOQN5B+PunspXRg==} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + + marked@13.0.3: + resolution: {integrity: sha512-rqRix3/TWzE9rIoFGIn8JmsVfhiuC8VIQ8IdX5TfzmeBucdY05/0UlzKaw0eVtpcN/OdVFpBk7CjKGo9iHJ/zA==} + engines: {node: '>= 18'} + hasBin: true + + mdast-util-to-hast@13.2.0: + resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + mermaid@11.3.0: + resolution: {integrity: sha512-fFmf2gRXLtlGzug4wpIGN+rQdZ30M8IZEB1D3eZkXNqC7puhqeURBcD/9tbwXsqBO+A6Nzzo3MSSepmnw5xSeg==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.1: + resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mlly@1.7.2: + resolution: {integrity: sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.0.9: + resolution: {integrity: sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==} + engines: {node: ^18 || >=20} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + oniguruma-to-es@3.1.0: + resolution: {integrity: sha512-BJ3Jy22YlgejHSO7Fvmz1kKazlaPmRSUH+4adTDUS/dKQ4wLxI+gALZ8updbaux7/m7fIlpgOZ5fp/Inq5jUAw==} + + open@10.1.0: + resolution: {integrity: sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==} + engines: {node: '>=18'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@8.2.0: + resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} + engines: {node: '>=18'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@3.0.0: + resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.2: + resolution: {integrity: sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + parse5-htmlparser2-tree-adapter@7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.1.2: + resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} + + path-data-parser@0.1.0: + resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + path-type@5.0.0: + resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} + engines: {node: '>=12'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + photoswipe@5.4.4: + resolution: {integrity: sha512-WNFHoKrkZNnvFFhbHL93WDkW3ifwVOXSW3w1UuZZelSmgXpIGiZSNlZJq37rR8YejqME2rHs9EhH9ZvlvFH2NA==} + engines: {node: '>= 0.12.0'} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pkg-types@1.2.1: + resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + points-on-curve@0.2.0: + resolution: {integrity: sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==} + + points-on-path@0.2.1: + resolution: {integrity: sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-selector-parser@6.1.1: + resolution: {integrity: sha512-b4dlw/9V8A71rLIDsSwVmak9z2DuBUB7CA1/wSdelNEzqsjoSPeADTWNO09lpH49Diy3/JIZ2bSPB1dI3LJCHg==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.4.41: + resolution: {integrity: sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.2: + resolution: {integrity: sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@2.3.2: + resolution: {integrity: sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==} + engines: {node: '>=10.13.0'} + hasBin: true + + pretty-ms@9.0.0: + resolution: {integrity: sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==} + engines: {node: '>=18'} + + property-information@6.5.0: + resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.1: + resolution: {integrity: sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==} + engines: {node: '>= 14.18.0'} + + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + + regenerate-unicode-properties@10.1.1: + resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.0.1: + resolution: {integrity: sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==} + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + + regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + + rollup@4.34.6: + resolution: {integrity: sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + roughjs@4.6.6: + resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} + + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass-loader@15.0.0: + resolution: {integrity: sha512-mbXAL7sI/fgt3skXR6xHxtKkaGyxRrGf7zrU4hLLWxBDJEcAe0QsoNy92qKttCb3zfMniTkU2kD9yakUKtW7vQ==} + engines: {node: '>= 18.12.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + sass: ^1.3.0 + sass-embedded: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + node-sass: + optional: true + sass: + optional: true + sass-embedded: + optional: true + webpack: + optional: true + + sass@1.84.0: + resolution: {integrity: sha512-XDAbhEPJRxi7H0SxrnOpiXFQoUJHwkR2u3Zc4el+fK/Tt5Hpzw5kkQ59qVDfvdaUq6gCrEZIbySFBM2T9DNKHg==} + engines: {node: '>=14.0.0'} + hasBin: true + + sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + + shiki@2.3.2: + resolution: {integrity: sha512-UZhz/gsUz7DHFbQBOJP7eXqvKyYvMGramxQiSDc83M/7OkWm6OdVHAReEc3vMLh6L6TRhgL9dvhXz9XDkCDaaw==} + + shx@0.3.3: + resolution: {integrity: sha512-nZJ3HFWVoTSyyB+evEKjJ1STiixGztlqwKLTUNV5KqMWtGey9fTd4KU1gdZ1X9BV6215pswQ/Jew9NsuS/fNDA==} + engines: {node: '>=6'} + hasBin: true + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sitemap@8.0.0: + resolution: {integrity: sha512-+AbdxhM9kJsHtruUF39bwS/B0Fytw6Fr1o4ZAIAEqA6cke2xcoO2GleBw9Zw7nRzILVEgz7zBM5GiTJjie1G9A==} + engines: {node: '>=14.0.0', npm: '>=6.0.0'} + hasBin: true + + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-resolve@0.6.0: + resolution: {integrity: sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + stylis@4.3.4: + resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} + + stylus@0.56.0: + resolution: {integrity: sha512-Ev3fOb4bUElwWu4F9P9WjnnaSpc8XB9OFHSFZSKMFL1CE1oM+oFXWEgAqPmmZIyhBihuqIQlFsVTypiiS9RxeA==} + hasBin: true + + superjson@2.2.1: + resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==} + engines: {node: '>=16'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tsconfig-vuepress@4.5.0: + resolution: {integrity: sha512-edJbEJwTQayS4+q5mIPsVY9UaZfgzJezNX/eO86rRgIIDsJyVdcUahr7WgqQWdYI7MIcdDvMRlSn0+Veznmq5g==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + undici@6.21.1: + resolution: {integrity: sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==} + engines: {node: '>=18.17'} + + unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + + unicorn-magic@0.1.0: + resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + engines: {node: '>=18'} + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unist-util-is@6.0.0: + resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.1: + resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} + + unist-util-visit@5.0.0: + resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + + universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + + upath@2.0.1: + resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} + engines: {node: '>=4'} + + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + vfile-message@4.0.2: + resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + vite-hot-client@0.2.3: + resolution: {integrity: sha512-rOGAV7rUlUHX89fP2p2v0A2WWvV3QMX2UYq0fRqsWSvFvev4atHWqjwGoKaZT1VTKyLGk533ecu3eyd0o59CAg==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 + + vite-plugin-inspect@0.8.5: + resolution: {integrity: sha512-JvTUqsP1JNDw0lMZ5Z/r5cSj81VK2B7884LO1DC3GMBhdcjcsAnJjdWq7bzQL01Xbh+v60d3lju3g+z7eAtNew==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^3.1.0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + + vite-plugin-vue-devtools@7.3.8: + resolution: {integrity: sha512-b5t4wxCb5g5cjh+odNpgnB7iX7gA6FJnKugFqX2/YZX9I4fvMjlj1bUnCKnvPlmwnFxClYgdmgZcCh2RyhZgvw==} + engines: {node: '>=v14.21.3'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0-0 || ^5.0.0-0 + + vite-plugin-vue-inspector@5.1.3: + resolution: {integrity: sha512-pMrseXIDP1Gb38mOevY+BvtNGNqiqmqa2pKB99lnLsADQww9w9xMbAfT4GB6RUoaOkSPrtlXqpq2Fq+Dj2AgFg==} + peerDependencies: + vite: ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 + + vite@6.0.11: + resolution: {integrity: sha512-4VL9mQPKoHy4+FE0NnRE/kbY51TOfaknxAjt3fJbGJxhIpBZiqVzlZDEesWWsuREXHwNdAoOFZ9MkPEVXczHwg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + vue-demi@0.13.11: + resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + vue-router@4.4.0: + resolution: {integrity: sha512-HB+t2p611aIZraV2aPSRNXf0Z/oLZFrlygJm+sZbdJaW6lcFqEDQwnzUBXn+DApw+/QzDU/I9TeWx9izEjTmsA==} + peerDependencies: + vue: ^3.2.0 + + vue-router@4.5.0: + resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==} + peerDependencies: + vue: ^3.2.0 + + vue@3.4.31: + resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vuepress-plugin-components@2.0.0-rc.71: + resolution: {integrity: sha512-0EN/RgVUpinQaoLwqozYEzxhI8xHT+oDv0B6bw4DI6pFSlUzDP2adE1rw9UYeZDbVMZ9CD1SxuCLvc0dGEIGbw==} + engines: {node: '>=18.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + peerDependencies: + artplayer: ^5.0.0 + dashjs: 4.7.4 + hls.js: ^1.4.12 + mpegts.js: ^1.7.3 + sass: ^1.81.0 + sass-embedded: ^1.81.0 + sass-loader: ^16.0.2 + vidstack: ^1.12.9 + vuepress: 2.0.0-rc.19 + peerDependenciesMeta: + artplayer: + optional: true + dashjs: + optional: true + hls.js: + optional: true + mpegts.js: + optional: true + sass: + optional: true + sass-embedded: + optional: true + sass-loader: + optional: true + vidstack: + optional: true + + vuepress-plugin-md-enhance@2.0.0-rc.71: + resolution: {integrity: sha512-0w5PAXUE4z9hFcM7ig/BlBn874JzX+7B59TPUWrehyeVfdldPPGA5m1v0+30+9jGotANk5cwfhqtI0KT7Lrn3Q==} + engines: {node: '>=18.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + peerDependencies: + '@vue/repl': ^4.1.1 + chart.js: ^4.0.0 + echarts: ^5.0.0 + flowchart.ts: ^3.0.0 + kotlin-playground: ^1.23.0 + markmap-lib: ^0.18.5 + markmap-toolbar: ^0.18.5 + markmap-view: ^0.18.5 + mermaid: ^11.2.0 + sandpack-vue3: ^3.0.0 + sass: ^1.81.0 + sass-embedded: ^1.81.0 + sass-loader: ^16.0.2 + vuepress: 2.0.0-rc.19 + peerDependenciesMeta: + '@vue/repl': + optional: true + chart.js: + optional: true + echarts: + optional: true + flowchart.ts: + optional: true + kotlin-playground: + optional: true + markmap-lib: + optional: true + markmap-toolbar: + optional: true + markmap-view: + optional: true + mermaid: + optional: true + sandpack-vue3: + optional: true + sass: + optional: true + sass-embedded: + optional: true + sass-loader: + optional: true + + vuepress-shared@2.0.0-rc.71: + resolution: {integrity: sha512-hdRZx4Qtr5uSVs8Tx61il8pXgeBpa5BnruEIFvcy/kjOUblqPjX/NwxThWPSHO4AjRAz4zQ8Gq9JcXh2c/m7Ow==} + engines: {node: '>=18.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + peerDependencies: + vuepress: 2.0.0-rc.19 + + vuepress-theme-hope@2.0.0-rc.71: + resolution: {integrity: sha512-tZbdXIYiYZHYLIhNdxWTHnbjCKhJWTFFkCqC73jBqBr9gqYyuzfQ/fSPWh/xaqwe/v33AUzJ2QHKao86m78mjg==} + engines: {node: '>=18.19.0', npm: '>=8', pnpm: '>=7', yarn: '>=2'} + peerDependencies: + '@vuepress/plugin-docsearch': 2.0.0-rc.74 + '@vuepress/plugin-feed': 2.0.0-rc.74 + '@vuepress/plugin-prismjs': 2.0.0-rc.74 + '@vuepress/plugin-pwa': 2.0.0-rc.74 + '@vuepress/plugin-revealjs': 2.0.0-rc.74 + '@vuepress/plugin-search': 2.0.0-rc.74 + '@vuepress/plugin-slimsearch': 2.0.0-rc.74 + '@vuepress/plugin-watermark': 2.0.0-rc.74 + nodejs-jieba: ^0.2.1 + sass: ^1.81.0 + sass-embedded: ^1.81.0 + sass-loader: ^16.0.2 + vuepress: 2.0.0-rc.19 + peerDependenciesMeta: + '@vuepress/plugin-docsearch': + optional: true + '@vuepress/plugin-feed': + optional: true + '@vuepress/plugin-prismjs': + optional: true + '@vuepress/plugin-pwa': + optional: true + '@vuepress/plugin-revealjs': + optional: true + '@vuepress/plugin-search': + optional: true + '@vuepress/plugin-slimsearch': + optional: true + '@vuepress/plugin-watermark': + optional: true + nodejs-jieba: + optional: true + sass: + optional: true + sass-embedded: + optional: true + sass-loader: + optional: true + + vuepress@2.0.0-rc.19: + resolution: {integrity: sha512-JDeuPTu14Kprdqx2geAryjFJvUzVaMnOLewlAgwVuZTygDWb8cgXhu9/p6rqzzdHETtIrvjbASBhH7JPyqmxmA==} + engines: {node: ^18.19.0 || >=20.4.0} + hasBin: true + peerDependencies: + '@vuepress/bundler-vite': 2.0.0-rc.19 + '@vuepress/bundler-webpack': 2.0.0-rc.19 + vue: ^3.5.0 + peerDependenciesMeta: + '@vuepress/bundler-vite': + optional: true + '@vuepress/bundler-webpack': + optional: true + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@antfu/install-pkg@0.4.1': + dependencies: + package-manager-detector: 0.2.2 + tinyexec: 0.3.1 + + '@antfu/utils@0.7.10': {} + + '@babel/cli@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@jridgewell/trace-mapping': 0.3.25 + commander: 6.2.1 + convert-source-map: 2.0.0 + fs-readdir-recursive: 1.1.0 + glob: 7.2.3 + make-dir: 2.1.0 + slash: 2.0.0 + optionalDependencies: + '@nicolo-ribaudo/chokidar-2': 2.1.8-no-fsevents.3 + chokidar: 3.6.0 + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + + '@babel/compat-data@7.25.2': {} + + '@babel/core@7.25.2': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + convert-source-map: 2.0.0 + debug: 4.3.5 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.0': + dependencies: + '@babel/types': 7.25.2 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-annotate-as-pure@7.24.7': + dependencies: + '@babel/types': 7.24.8 + + '@babel/helper-builder-binary-assignment-operator-visitor@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-compilation-targets@7.25.2': + dependencies: + '@babel/compat-data': 7.25.2 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.23.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/traverse': 7.25.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + regexpu-core: 5.3.2 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + debug: 4.3.5 + lodash.debounce: 4.0.8 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.24.8': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.22.15': + dependencies: + '@babel/types': 7.24.8 + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.24.7': + dependencies: + '@babel/types': 7.24.8 + + '@babel/helper-plugin-utils@7.24.8': {} + + '@babel/helper-remap-async-to-generator@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-wrap-function': 7.25.0 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-member-expression-to-functions': 7.24.8 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + dependencies: + '@babel/traverse': 7.25.3 + '@babel/types': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.24.8': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/helper-validator-option@7.24.8': {} + + '@babel/helper-wrap-function@7.25.0': + dependencies: + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.25.0': + dependencies: + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + '@babel/parser@7.24.7': + dependencies: + '@babel/types': 7.24.8 + + '@babel/parser@7.25.3': + dependencies: + '@babel/types': 7.25.2 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-decorators@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-decorators': 7.24.7(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-decorators@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-async-generator-functions@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-remap-async-to-generator': 7.25.0(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-block-scoping@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + '@babel/traverse': 7.25.3 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/template': 7.25.0 + + '@babel/plugin-transform-destructuring@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-for-of@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.25.1(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-literals@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + + '@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-simple-access': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.25.0(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + '@babel/traverse': 7.25.3 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-new-target@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + + '@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + + '@babel/plugin-transform-object-super@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-replace-supers': 7.25.0(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + + '@babel/plugin-transform-optional-chaining@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + regenerator-transform: 0.15.2 + + '@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-spread@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-typeof-symbol@7.24.8(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-typescript@7.25.2(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.25.0(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-create-regexp-features-plugin': 7.25.2(@babel/core@7.25.2) + '@babel/helper-plugin-utils': 7.24.8 + + '@babel/preset-env@7.25.3(@babel/core@7.25.2)': + dependencies: + '@babel/compat-data': 7.25.2 + '@babel/core': 7.25.2 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.3(@babel/core@7.25.2) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.25.2) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.25.2) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.25.2) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.25.2) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.25.2) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.25.2) + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-async-generator-functions': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-block-scoping': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-classes': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-destructuring': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-function-name': 7.25.1(@babel/core@7.25.2) + '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-literals': 7.25.2(@babel/core@7.25.2) + '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-modules-systemjs': 7.25.0(@babel/core@7.25.2) + '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-optional-chaining': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-typeof-symbol': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.25.2) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.25.2) + babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.25.2) + babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.25.2) + babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.25.2) + core-js-compat: 3.38.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/types': 7.24.8 + esutils: 2.0.3 + + '@babel/preset-typescript@7.24.7(@babel/core@7.25.2)': + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/helper-validator-option': 7.24.8 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-modules-commonjs': 7.24.8(@babel/core@7.25.2) + '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + '@babel/regjsgen@0.8.0': {} + + '@babel/runtime@7.25.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.25.0': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.25.3 + '@babel/types': 7.25.2 + + '@babel/traverse@7.25.3': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.25.0 + '@babel/parser': 7.25.3 + '@babel/template': 7.25.0 + '@babel/types': 7.25.2 + debug: 4.3.5 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.24.8': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@babel/types@7.25.2': + dependencies: + '@babel/helper-string-parser': 7.24.8 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@braintree/sanitize-url@7.1.0': {} + + '@chevrotain/cst-dts-gen@11.0.3': + dependencies: + '@chevrotain/gast': 11.0.3 + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/gast@11.0.3': + dependencies: + '@chevrotain/types': 11.0.3 + lodash-es: 4.17.21 + + '@chevrotain/regexp-to-ast@11.0.3': {} + + '@chevrotain/types@11.0.3': {} + + '@chevrotain/utils@11.0.3': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/aix-ppc64@0.24.2': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.24.2': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-arm@0.24.2': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/android-x64@0.24.2': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.24.2': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.24.2': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.24.2': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.24.2': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.24.2': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.24.2': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.24.2': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.24.2': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.24.2': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.24.2': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.24.2': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.24.2': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.24.2': + optional: true + + '@esbuild/netbsd-arm64@0.24.2': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.24.2': + optional: true + + '@esbuild/openbsd-arm64@0.24.2': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.24.2': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.24.2': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.24.2': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.24.2': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@esbuild/win32-x64@0.24.2': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': + dependencies: + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.0': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.5 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.0': {} + + '@humanwhocodes/config-array@0.11.14': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.5 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.1.33': + dependencies: + '@antfu/install-pkg': 0.4.1 + '@antfu/utils': 0.7.10 + '@iconify/types': 2.0.0 + debug: 4.3.7 + kolorist: 1.8.0 + local-pkg: 0.5.0 + mlly: 1.7.2 + transitivePeerDependencies: + - supports-color + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@lit-labs/ssr-dom-shim@1.2.1': {} + + '@lit/reactive-element@2.0.4': + dependencies: + '@lit-labs/ssr-dom-shim': 1.2.1 + + '@mdit-vue/plugin-component@2.1.3': + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + '@mdit-vue/plugin-frontmatter@2.1.3': + dependencies: + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.1.2 + gray-matter: 4.0.3 + markdown-it: 14.1.0 + + '@mdit-vue/plugin-headers@2.1.3': + dependencies: + '@mdit-vue/shared': 2.1.3 + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + '@mdit-vue/plugin-sfc@2.1.3': + dependencies: + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + '@mdit-vue/plugin-title@2.1.3': + dependencies: + '@mdit-vue/shared': 2.1.3 + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + '@mdit-vue/plugin-toc@2.1.3': + dependencies: + '@mdit-vue/shared': 2.1.3 + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + '@mdit-vue/shared@2.1.3': + dependencies: + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + '@mdit-vue/types@2.1.0': {} + + '@mdit/helper@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-alert@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-align@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/plugin-container': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-attrs@0.16.7(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-container@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-demo@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-dl@0.13.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-figure@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-footnote@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + '@mdit/plugin-icon@0.16.5(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-img-lazyload@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-img-mark@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-img-size@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-include@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + upath: 2.0.1 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-katex-slim@0.16.7(katex@0.16.11)(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-tex': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + katex: 0.16.11 + markdown-it: 14.1.0 + + '@mdit/plugin-mark@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-mathjax-slim@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/plugin-tex': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + upath: 2.0.1 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-plantuml@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/plugin-uml': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-spoiler@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-stylize@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-sub@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-sup@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-tab@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-tasklist@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-tex@0.16.0(markdown-it@14.1.0)': + dependencies: + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mdit/plugin-uml@0.16.0(markdown-it@14.1.0)': + dependencies: + '@mdit/helper': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + optionalDependencies: + markdown-it: 14.1.0 + + '@mermaid-js/parser@0.3.0': + dependencies: + langium: 3.0.0 + + '@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.3': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + + '@parcel/watcher-android-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.1': + optional: true + + '@parcel/watcher-darwin-x64@2.5.1': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.1': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.1': + optional: true + + '@parcel/watcher-win32-arm64@2.5.1': + optional: true + + '@parcel/watcher-win32-ia32@2.5.1': + optional: true + + '@parcel/watcher-win32-x64@2.5.1': + optional: true + + '@parcel/watcher@2.5.1': + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.8 + node-addon-api: 7.1.1 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.1 + '@parcel/watcher-darwin-arm64': 2.5.1 + '@parcel/watcher-darwin-x64': 2.5.1 + '@parcel/watcher-freebsd-x64': 2.5.1 + '@parcel/watcher-linux-arm-glibc': 2.5.1 + '@parcel/watcher-linux-arm-musl': 2.5.1 + '@parcel/watcher-linux-arm64-glibc': 2.5.1 + '@parcel/watcher-linux-arm64-musl': 2.5.1 + '@parcel/watcher-linux-x64-glibc': 2.5.1 + '@parcel/watcher-linux-x64-musl': 2.5.1 + '@parcel/watcher-win32-arm64': 2.5.1 + '@parcel/watcher-win32-ia32': 2.5.1 + '@parcel/watcher-win32-x64': 2.5.1 + optional: true + + '@pkgr/core@0.1.1': {} + + '@polka/url@1.0.0-next.25': {} + + '@rollup/plugin-alias@3.1.9(rollup@4.34.6)': + dependencies: + rollup: 4.34.6 + slash: 3.0.0 + + '@rollup/pluginutils@5.1.0(rollup@4.34.6)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.34.6 + + '@rollup/rollup-android-arm-eabi@4.34.6': + optional: true + + '@rollup/rollup-android-arm64@4.34.6': + optional: true + + '@rollup/rollup-darwin-arm64@4.34.6': + optional: true + + '@rollup/rollup-darwin-x64@4.34.6': + optional: true + + '@rollup/rollup-freebsd-arm64@4.34.6': + optional: true + + '@rollup/rollup-freebsd-x64@4.34.6': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.34.6': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.34.6': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.34.6': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.34.6': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.34.6': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.34.6': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.34.6': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.34.6': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.34.6': + optional: true + + '@rollup/rollup-linux-x64-musl@4.34.6': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.34.6': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.34.6': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.34.6': + optional: true + + '@sec-ant/readable-stream@0.4.1': {} + + '@shikijs/core@2.3.2': + dependencies: + '@shikijs/engine-javascript': 2.3.2 + '@shikijs/engine-oniguruma': 2.3.2 + '@shikijs/types': 2.3.2 + '@shikijs/vscode-textmate': 10.0.1 + '@types/hast': 3.0.4 + hast-util-to-html: 9.0.4 + + '@shikijs/engine-javascript@2.3.2': + dependencies: + '@shikijs/types': 2.3.2 + '@shikijs/vscode-textmate': 10.0.1 + oniguruma-to-es: 3.1.0 + + '@shikijs/engine-oniguruma@2.3.2': + dependencies: + '@shikijs/types': 2.3.2 + '@shikijs/vscode-textmate': 10.0.1 + + '@shikijs/langs@2.3.2': + dependencies: + '@shikijs/types': 2.3.2 + + '@shikijs/themes@2.3.2': + dependencies: + '@shikijs/types': 2.3.2 + + '@shikijs/transformers@2.3.2': + dependencies: + '@shikijs/core': 2.3.2 + '@shikijs/types': 2.3.2 + + '@shikijs/types@2.3.2': + dependencies: + '@shikijs/vscode-textmate': 10.0.1 + '@types/hast': 3.0.4 + + '@shikijs/vscode-textmate@10.0.1': {} + + '@sindresorhus/merge-streams@2.3.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@stackblitz/sdk@1.11.0': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.31 + + '@types/estree@1.0.6': {} + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 17.0.45 + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 17.0.45 + + '@types/hash-sum@1.0.2': {} + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/json5@0.0.29': {} + + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 17.0.45 + + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it-emoji@3.0.1': + dependencies: + '@types/markdown-it': 14.1.2 + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mdurl@2.0.0': {} + + '@types/minimatch@5.1.2': {} + + '@types/ms@0.7.31': {} + + '@types/node@17.0.45': {} + + '@types/sax@1.2.7': + dependencies: + '@types/node': 17.0.45 + + '@types/trusted-types@2.0.7': {} + + '@types/unist@3.0.3': {} + + '@types/web-bluetooth@0.0.20': {} + + '@typescript-eslint/eslint-plugin@7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3)': + dependencies: + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 7.16.0(eslint@8.57.0)(typescript@5.5.3) + '@typescript-eslint/scope-manager': 7.16.0 + '@typescript-eslint/type-utils': 7.16.0(eslint@8.57.0)(typescript@5.5.3) + '@typescript-eslint/utils': 7.16.0(eslint@8.57.0)(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 7.16.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3)': + dependencies: + '@typescript-eslint/scope-manager': 7.16.0 + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 7.16.0 + debug: 4.3.5 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.16.0': + dependencies: + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/visitor-keys': 7.16.0 + + '@typescript-eslint/type-utils@7.16.0(eslint@8.57.0)(typescript@5.5.3)': + dependencies: + '@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3) + '@typescript-eslint/utils': 7.16.0(eslint@8.57.0)(typescript@5.5.3) + debug: 4.3.5 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.16.0': {} + + '@typescript-eslint/typescript-estree@7.16.0(typescript@5.5.3)': + dependencies: + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/visitor-keys': 7.16.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.16.0(eslint@8.57.0)(typescript@5.5.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.16.0 + '@typescript-eslint/types': 7.16.0 + '@typescript-eslint/typescript-estree': 7.16.0(typescript@5.5.3) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.16.0': + dependencies: + '@typescript-eslint/types': 7.16.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@vitejs/plugin-vue@5.2.1(vite@6.0.11(sass@1.84.0)(stylus@0.56.0))(vue@3.5.13(typescript@5.5.3))': + dependencies: + vite: 6.0.11(sass@1.84.0)(stylus@0.56.0) + vue: 3.5.13(typescript@5.5.3) + + '@vue/babel-helper-vue-transform-on@1.2.2': {} + + '@vue/babel-plugin-jsx@1.2.2(@babel/core@7.25.2)': + dependencies: + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2) + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.3 + '@babel/types': 7.24.8 + '@vue/babel-helper-vue-transform-on': 1.2.2 + '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.25.2) + camelcase: 6.3.0 + html-tags: 3.3.1 + svg-tags: 1.0.0 + optionalDependencies: + '@babel/core': 7.25.2 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.2.2(@babel/core@7.25.2)': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/core': 7.25.2 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.24.8 + '@babel/parser': 7.24.7 + '@vue/compiler-sfc': 3.4.38 + + '@vue/compiler-core@3.4.31': + dependencies: + '@babel/parser': 7.24.7 + '@vue/shared': 3.4.31 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-core@3.4.38': + dependencies: + '@babel/parser': 7.24.7 + '@vue/shared': 3.4.38 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.25.3 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.4.31': + dependencies: + '@vue/compiler-core': 3.4.31 + '@vue/shared': 3.4.31 + + '@vue/compiler-dom@3.4.38': + dependencies: + '@vue/compiler-core': 3.4.38 + '@vue/shared': 3.4.38 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.4.31': + dependencies: + '@babel/parser': 7.24.7 + '@vue/compiler-core': 3.4.31 + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.41 + source-map-js: 1.2.0 + + '@vue/compiler-sfc@3.4.38': + dependencies: + '@babel/parser': 7.24.7 + '@vue/compiler-core': 3.4.38 + '@vue/compiler-dom': 3.4.38 + '@vue/compiler-ssr': 3.4.38 + '@vue/shared': 3.4.38 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.41 + source-map-js: 1.2.1 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.25.3 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.17 + postcss: 8.5.2 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.4.31': + dependencies: + '@vue/compiler-dom': 3.4.31 + '@vue/shared': 3.4.31 + + '@vue/compiler-ssr@3.4.38': + dependencies: + '@vue/compiler-dom': 3.4.38 + '@vue/shared': 3.4.38 + + '@vue/compiler-ssr@3.5.13': + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/devtools-api@6.6.3': {} + + '@vue/devtools-api@6.6.4': {} + + '@vue/devtools-api@7.7.2': + dependencies: + '@vue/devtools-kit': 7.7.2 + + '@vue/devtools-core@7.3.8(vite@6.0.11(sass@1.84.0)(stylus@0.56.0))(vue@3.4.31(typescript@5.5.3))': + dependencies: + '@vue/devtools-kit': 7.3.8 + '@vue/devtools-shared': 7.3.8 + mitt: 3.0.1 + nanoid: 3.3.7 + pathe: 1.1.2 + vite-hot-client: 0.2.3(vite@6.0.11(sass@1.84.0)(stylus@0.56.0)) + vue: 3.4.31(typescript@5.5.3) + transitivePeerDependencies: + - vite + + '@vue/devtools-kit@7.3.8': + dependencies: + '@vue/devtools-shared': 7.3.8 + birpc: 0.2.17 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + + '@vue/devtools-kit@7.7.2': + dependencies: + '@vue/devtools-shared': 7.7.2 + birpc: 0.2.19 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + superjson: 2.2.1 + + '@vue/devtools-shared@7.3.8': + dependencies: + rfdc: 1.4.1 + + '@vue/devtools-shared@7.7.2': + dependencies: + rfdc: 1.4.1 + + '@vue/reactivity@3.4.31': + dependencies: + '@vue/shared': 3.4.31 + + '@vue/reactivity@3.5.13': + dependencies: + '@vue/shared': 3.5.13 + + '@vue/runtime-core@3.4.31': + dependencies: + '@vue/reactivity': 3.4.31 + '@vue/shared': 3.4.31 + + '@vue/runtime-core@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/runtime-dom@3.4.31': + dependencies: + '@vue/reactivity': 3.4.31 + '@vue/runtime-core': 3.4.31 + '@vue/shared': 3.4.31 + csstype: 3.1.3 + + '@vue/runtime-dom@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.31(vue@3.4.31(typescript@5.5.3))': + dependencies: + '@vue/compiler-ssr': 3.4.31 + '@vue/shared': 3.4.31 + vue: 3.4.31(typescript@5.5.3) + + '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.5.3))': + dependencies: + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13(typescript@5.5.3) + + '@vue/shared@3.4.31': {} + + '@vue/shared@3.4.38': {} + + '@vue/shared@3.5.13': {} + + '@vuelidate/core@2.0.3(vue@3.4.31(typescript@5.5.3))': + dependencies: + vue: 3.4.31(typescript@5.5.3) + vue-demi: 0.13.11(vue@3.4.31(typescript@5.5.3)) + + '@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3)': + dependencies: + '@vitejs/plugin-vue': 5.2.1(vite@6.0.11(sass@1.84.0)(stylus@0.56.0))(vue@3.5.13(typescript@5.5.3)) + '@vuepress/bundlerutils': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/client': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/core': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/shared': 2.0.0-rc.19 + '@vuepress/utils': 2.0.0-rc.19 + autoprefixer: 10.4.20(postcss@8.5.2) + connect-history-api-fallback: 2.0.0 + postcss: 8.5.2 + postcss-load-config: 6.0.1(postcss@8.5.2) + rollup: 4.34.6 + vite: 6.0.11(sass@1.84.0)(stylus@0.56.0) + vue: 3.5.13(typescript@5.5.3) + vue-router: 4.5.0(vue@3.5.13(typescript@5.5.3)) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - typescript + - yaml + + '@vuepress/bundlerutils@2.0.0-rc.19(typescript@5.5.3)': + dependencies: + '@vuepress/client': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/core': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/shared': 2.0.0-rc.19 + '@vuepress/utils': 2.0.0-rc.19 + vue: 3.5.13(typescript@5.5.3) + vue-router: 4.5.0(vue@3.5.13(typescript@5.5.3)) + transitivePeerDependencies: + - supports-color + - typescript + + '@vuepress/cli@2.0.0-rc.19(typescript@5.5.3)': + dependencies: + '@vuepress/core': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/shared': 2.0.0-rc.19 + '@vuepress/utils': 2.0.0-rc.19 + cac: 6.7.14 + chokidar: 3.6.0 + envinfo: 7.14.0 + esbuild: 0.21.5 + transitivePeerDependencies: + - supports-color + - typescript + + '@vuepress/client@2.0.0-rc.19(typescript@5.5.3)': + dependencies: + '@vue/devtools-api': 7.7.2 + '@vuepress/shared': 2.0.0-rc.19 + vue: 3.5.13(typescript@5.5.3) + vue-router: 4.5.0(vue@3.5.13(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/core@2.0.0-rc.19(typescript@5.5.3)': + dependencies: + '@vuepress/client': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/markdown': 2.0.0-rc.19 + '@vuepress/shared': 2.0.0-rc.19 + '@vuepress/utils': 2.0.0-rc.19 + vue: 3.5.13(typescript@5.5.3) + transitivePeerDependencies: + - supports-color + - typescript + + '@vuepress/helper@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vue/shared': 3.5.13 + '@vueuse/core': 12.5.0(typescript@5.5.3) + cheerio: 1.0.0 + fflate: 0.8.2 + gray-matter: 4.0.3 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/highlighter-helper@2.0.0-rc.71(@vueuse/core@12.5.0(typescript@5.5.3))(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + optionalDependencies: + '@vueuse/core': 12.5.0(typescript@5.5.3) + + '@vuepress/markdown@2.0.0-rc.19': + dependencies: + '@mdit-vue/plugin-component': 2.1.3 + '@mdit-vue/plugin-frontmatter': 2.1.3 + '@mdit-vue/plugin-headers': 2.1.3 + '@mdit-vue/plugin-sfc': 2.1.3 + '@mdit-vue/plugin-title': 2.1.3 + '@mdit-vue/plugin-toc': 2.1.3 + '@mdit-vue/shared': 2.1.3 + '@mdit-vue/types': 2.1.0 + '@types/markdown-it': 14.1.2 + '@types/markdown-it-emoji': 3.0.1 + '@vuepress/shared': 2.0.0-rc.19 + '@vuepress/utils': 2.0.0-rc.19 + markdown-it: 14.1.0 + markdown-it-anchor: 9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.0) + markdown-it-emoji: 3.0.0 + mdurl: 2.0.0 + transitivePeerDependencies: + - supports-color + + '@vuepress/plugin-active-header-links@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-back-to-top@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-blog@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + chokidar: 3.6.0 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-catalog@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-comment@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + giscus: 1.6.0 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-copy-code@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-copyright@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-git@2.0.0-rc.68(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + execa: 9.5.2 + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + + '@vuepress/plugin-icon@2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-icon': 0.16.5(markdown-it@14.1.0) + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-links-check@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-markdown-ext@2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-container': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-footnote': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-tasklist': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + js-yaml: 4.1.0 + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-markdown-hint@2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-alert': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-container': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-markdown-image@2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-figure': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-img-lazyload': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-img-mark': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-img-size': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-markdown-include@2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-include': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-markdown-math@2.0.0-rc.74(katex@0.16.11)(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-katex-slim': 0.16.7(katex@0.16.11)(markdown-it@14.1.0) + '@mdit/plugin-mathjax-slim': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + optionalDependencies: + katex: 0.16.11 + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-markdown-stylize@2.0.0-rc.75(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-align': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-attrs': 0.16.7(markdown-it@14.1.0) + '@mdit/plugin-mark': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-spoiler': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-stylize': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-sub': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-sup': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-markdown-tab@2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@mdit/plugin-tab': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - markdown-it + - typescript + + '@vuepress/plugin-notice@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-nprogress@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-photo-swipe@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + photoswipe: 5.4.4 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-reading-time@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-redirect@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + commander: 13.1.0 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-rtl@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-sass-palette@2.0.0-rc.74(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + chokidar: 4.0.3 + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + optionalDependencies: + sass: 1.84.0 + sass-loader: 15.0.0(sass@1.84.0) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-search@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + chokidar: 3.6.0 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-seo@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-shiki@2.0.0-rc.74(@vueuse/core@12.5.0(typescript@5.5.3))(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@shikijs/transformers': 2.3.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/highlighter-helper': 2.0.0-rc.71(@vueuse/core@12.5.0(typescript@5.5.3))(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + nanoid: 5.0.9 + shiki: 2.3.2 + synckit: 0.9.2 + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - '@vueuse/core' + - typescript + + '@vuepress/plugin-sitemap@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + sitemap: 8.0.0 + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/plugin-theme-data@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)))': + dependencies: + '@vue/devtools-api': 7.7.2 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + '@vuepress/shared@2.0.0-rc.19': + dependencies: + '@mdit-vue/types': 2.1.0 + + '@vuepress/utils@2.0.0-rc.19': + dependencies: + '@types/debug': 4.1.12 + '@types/fs-extra': 11.0.4 + '@types/hash-sum': 1.0.2 + '@vuepress/shared': 2.0.0-rc.19 + debug: 4.4.0 + fs-extra: 11.2.0 + globby: 14.0.2 + hash-sum: 2.0.0 + ora: 8.2.0 + picocolors: 1.1.1 + upath: 2.0.1 + transitivePeerDependencies: + - supports-color + + '@vueuse/core@12.5.0(typescript@5.5.3)': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 12.5.0 + '@vueuse/shared': 12.5.0(typescript@5.5.3) + vue: 3.5.13(typescript@5.5.3) + transitivePeerDependencies: + - typescript + + '@vueuse/metadata@12.5.0': {} + + '@vueuse/shared@12.5.0(typescript@5.5.3)': + dependencies: + vue: 3.5.13(typescript@5.5.3) + transitivePeerDependencies: + - typescript + + acorn-jsx@5.3.2(acorn@8.12.1): + dependencies: + acorn: 8.12.1 + + acorn@8.12.1: {} + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.2: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@5.0.2: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-union@2.1.0: {} + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + atob@2.1.2: {} + + autoprefixer@10.4.20(postcss@8.5.2): + dependencies: + browserslist: 4.23.3 + caniuse-lite: 1.0.30001651 + fraction.js: 4.3.7 + normalize-range: 0.1.2 + picocolors: 1.0.1 + postcss: 8.5.2 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.25.2): + dependencies: + '@babel/compat-data': 7.25.2 + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.10.6(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + core-js-compat: 3.38.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.25.2): + dependencies: + '@babel/core': 7.25.2 + '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.25.2) + transitivePeerDependencies: + - supports-color + + balanced-match@1.0.2: {} + + balloon-css@1.2.0: {} + + bcrypt-ts@5.0.3: {} + + binary-extensions@2.2.0: {} + + birpc@0.2.17: {} + + birpc@0.2.19: {} + + boolbase@1.0.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.23.2: + dependencies: + caniuse-lite: 1.0.30001641 + electron-to-chromium: 1.4.825 + node-releases: 2.0.14 + update-browserslist-db: 1.1.0(browserslist@4.23.2) + + browserslist@4.23.3: + dependencies: + caniuse-lite: 1.0.30001651 + electron-to-chromium: 1.5.9 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) + + builtin-modules@3.3.0: {} + + builtins@5.1.0: + dependencies: + semver: 7.6.2 + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 + + cac@6.7.14: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001641: {} + + caniuse-lite@1.0.30001651: {} + + ccount@2.0.1: {} + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + encoding-sniffer: 0.2.0 + htmlparser2: 9.1.0 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + parse5-parser-stream: 7.1.2 + undici: 6.21.1 + whatwg-mimetype: 4.0.0 + + chevrotain-allstar@0.3.1(chevrotain@11.0.3): + dependencies: + chevrotain: 11.0.3 + lodash-es: 4.17.21 + + chevrotain@11.0.3: + dependencies: + '@chevrotain/cst-dts-gen': 11.0.3 + '@chevrotain/gast': 11.0.3 + '@chevrotain/regexp-to-ast': 11.0.3 + '@chevrotain/types': 11.0.3 + '@chevrotain/utils': 11.0.3 + lodash-es: 4.17.21 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.2 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.1 + + clean-stack@2.2.0: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-spinners@2.9.2: {} + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + comma-separated-tokens@2.0.3: {} + + commander@13.1.0: {} + + commander@6.2.1: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + connect-history-api-fallback@2.0.0: {} + + convert-source-map@2.0.0: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + core-js-compat@3.38.0: + dependencies: + browserslist: 4.23.3 + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cose-base@2.2.0: + dependencies: + layout-base: 2.0.1 + + create-codepen@2.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-what@6.1.0: {} + + css@3.0.0: + dependencies: + inherits: 2.0.4 + source-map: 0.6.1 + source-map-resolve: 0.6.0 + + cssesc@3.0.0: {} + + csstype@3.1.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.30.3): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.30.3 + + cytoscape-fcose@2.2.0(cytoscape@3.30.3): + dependencies: + cose-base: 2.2.0 + cytoscape: 3.30.3 + + cytoscape@3.30.3: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + dagre-d3-es@7.0.10: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + dayjs@1.11.12: {} + + dayjs@1.11.13: {} + + debug@3.2.7: + dependencies: + ms: 2.1.2 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + decode-uri-component@0.2.2: {} + + deep-is@0.1.4: {} + + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-lazy-prop@3.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + degit@2.8.4: {} + + del@5.1.0: + dependencies: + globby: 10.0.2 + graceful-fs: 4.2.11 + is-glob: 4.0.3 + is-path-cwd: 2.2.0 + is-path-inside: 3.0.3 + p-map: 3.0.0 + rimraf: 3.0.2 + slash: 3.0.0 + + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + + dequal@2.0.3: {} + + detect-libc@1.0.3: + optional: true + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dijkstrajs@1.0.3: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + dompurify@3.1.6: {} + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv@10.0.0: {} + + electron-to-chromium@1.4.825: {} + + electron-to-chromium@1.5.9: {} + + emoji-regex-xs@1.0.0: {} + + emoji-regex@10.3.0: {} + + emoji-regex@8.0.0: {} + + encoding-sniffer@0.2.0: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + entities@4.5.0: {} + + envinfo@7.14.0: {} + + error-stack-parser-es@0.1.5: {} + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.2 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + esbuild@0.24.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.24.2 + '@esbuild/android-arm': 0.24.2 + '@esbuild/android-arm64': 0.24.2 + '@esbuild/android-x64': 0.24.2 + '@esbuild/darwin-arm64': 0.24.2 + '@esbuild/darwin-x64': 0.24.2 + '@esbuild/freebsd-arm64': 0.24.2 + '@esbuild/freebsd-x64': 0.24.2 + '@esbuild/linux-arm': 0.24.2 + '@esbuild/linux-arm64': 0.24.2 + '@esbuild/linux-ia32': 0.24.2 + '@esbuild/linux-loong64': 0.24.2 + '@esbuild/linux-mips64el': 0.24.2 + '@esbuild/linux-ppc64': 0.24.2 + '@esbuild/linux-riscv64': 0.24.2 + '@esbuild/linux-s390x': 0.24.2 + '@esbuild/linux-x64': 0.24.2 + '@esbuild/netbsd-arm64': 0.24.2 + '@esbuild/netbsd-x64': 0.24.2 + '@esbuild/openbsd-arm64': 0.24.2 + '@esbuild/openbsd-x64': 0.24.2 + '@esbuild/sunos-x64': 0.24.2 + '@esbuild/win32-arm64': 0.24.2 + '@esbuild/win32-ia32': 0.24.2 + '@esbuild/win32-x64': 0.24.2 + + escalade@3.1.2: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + eslint-compat-utils@0.5.1(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + semver: 7.6.2 + + eslint-config-prettier@9.1.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-config-standard@17.1.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint-plugin-n@16.6.2(eslint@8.57.0))(eslint-plugin-promise@6.4.0(eslint@8.57.0))(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0) + eslint-plugin-n: 16.6.2(eslint@8.57.0) + eslint-plugin-promise: 6.4.0(eslint@8.57.0) + + eslint-config-vuepress-typescript@4.10.1(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint-plugin-n@16.6.2(eslint@8.57.0))(eslint-plugin-promise@6.4.0(eslint@8.57.0))(eslint@8.57.0)(typescript@5.5.3): + dependencies: + '@typescript-eslint/eslint-plugin': 7.16.0(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0)(typescript@5.5.3) + '@typescript-eslint/parser': 7.16.0(eslint@8.57.0)(typescript@5.5.3) + eslint-config-standard: 17.1.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint-plugin-n@16.6.2(eslint@8.57.0))(eslint-plugin-promise@6.4.0(eslint@8.57.0))(eslint@8.57.0) + eslint-config-vuepress: 4.10.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0) + eslint-plugin-vue: 9.27.0(eslint@8.57.0) + transitivePeerDependencies: + - eslint + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - eslint-plugin-import + - eslint-plugin-n + - eslint-plugin-promise + - supports-color + - typescript + + eslint-config-vuepress@4.10.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0): + dependencies: + eslint-config-prettier: 9.1.0(eslint@8.57.0) + eslint-config-standard: 17.1.0(eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0))(eslint-plugin-n@16.6.2(eslint@8.57.0))(eslint-plugin-promise@6.4.0(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0) + eslint-plugin-n: 16.6.2(eslint@8.57.0) + eslint-plugin-promise: 6.4.0(eslint@8.57.0) + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.14.0 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.16.0(eslint@8.57.0)(typescript@5.5.3) + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + transitivePeerDependencies: + - supports-color + + eslint-plugin-es-x@7.8.0(eslint@8.57.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 + eslint: 8.57.0 + eslint-compat-utils: 0.5.1(eslint@8.57.0) + + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint@8.57.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.16.0(eslint@8.57.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.14.0 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.16.0(eslint@8.57.0)(typescript@5.5.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-n@16.6.2(eslint@8.57.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + builtins: 5.1.0 + eslint: 8.57.0 + eslint-plugin-es-x: 7.8.0(eslint@8.57.0) + get-tsconfig: 4.7.5 + globals: 13.24.0 + ignore: 5.3.1 + is-builtin-module: 3.2.1 + is-core-module: 2.14.0 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 7.6.2 + + eslint-plugin-promise@6.4.0(eslint@8.57.0): + dependencies: + eslint: 8.57.0 + + eslint-plugin-vue@9.27.0(eslint@8.57.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + eslint: 8.57.0 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.1 + semver: 7.6.2 + vue-eslint-parser: 9.4.3(eslint@8.57.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.11.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.3.5 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@9.6.1: + dependencies: + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + execa@9.5.2: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.0.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.1 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.13.0: + dependencies: + reusify: 1.0.4 + + fflate@0.8.2: {} + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.0.0 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.3.1: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + fraction.js@4.3.7: {} + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + + fs-readdir-recursive@1.1.0: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.2.0: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stream@8.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + giscus@1.6.0: + dependencies: + lit: 3.2.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@10.0.2: + dependencies: + '@types/glob': 7.2.0 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + glob: 7.2.3 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + globby@14.0.2: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.2 + ignore: 5.3.1 + path-type: 5.0.0 + slash: 5.1.0 + unicorn-magic: 0.1.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + + hachure-fill@0.5.2: {} + + has-bigints@1.0.2: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hash-sum@2.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.4: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.0 + property-information: 6.5.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hookable@5.5.3: {} + + html-tags@3.3.1: {} + + html-void-elements@3.0.0: {} + + htmlparser2@9.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + human-signals@5.0.0: {} + + human-signals@8.0.0: {} + + iconify-icon@2.1.0: + dependencies: + '@iconify/types': 2.0.0 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.1: {} + + immutable@5.0.3: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + interpret@1.4.0: {} + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.2.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-callable@1.2.7: {} + + is-core-module@2.14.0: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-docker@3.0.0: {} + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-interactive@2.0.0: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-path-cwd@2.2.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@4.1.0: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@3.0.0: {} + + is-stream@4.0.1: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.0.0: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-what@4.1.16: {} + + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@0.5.0: {} + + jsesc@2.5.2: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + + katex@0.16.11: + dependencies: + commander: 8.3.0 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + khroma@2.1.0: {} + + kind-of@6.0.3: {} + + kolorist@1.8.0: {} + + langium@3.0.0: + dependencies: + chevrotain: 11.0.3 + chevrotain-allstar: 0.3.1(chevrotain@11.0.3) + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.0.8 + + layout-base@1.0.2: {} + + layout-base@2.0.1: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@3.1.2: {} + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + lit-element@4.1.0: + dependencies: + '@lit-labs/ssr-dom-shim': 1.2.1 + '@lit/reactive-element': 2.0.4 + lit-html: 3.2.0 + + lit-html@3.2.0: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@3.2.1: + dependencies: + '@lit/reactive-element': 2.0.4 + lit-element: 4.1.0 + lit-html: 3.2.0 + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.2 + pkg-types: 1.2.1 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.21: {} + + lodash.debounce@4.0.8: {} + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + log-symbols@6.0.0: + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + + markdown-it-anchor@9.2.0(@types/markdown-it@14.1.2)(markdown-it@14.1.0): + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + + markdown-it-emoji@3.0.0: {} + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + marked@13.0.3: {} + + mdast-util-to-hast@13.2.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.2.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.0.0 + vfile: 6.0.3 + + mdurl@2.0.0: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + mermaid@11.3.0: + dependencies: + '@braintree/sanitize-url': 7.1.0 + '@iconify/utils': 2.1.33 + '@mermaid-js/parser': 0.3.0 + cytoscape: 3.30.3 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.30.3) + cytoscape-fcose: 2.2.0(cytoscape@3.30.3) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.10 + dayjs: 1.11.12 + dompurify: 3.1.6 + katex: 0.16.11 + khroma: 2.1.0 + lodash-es: 4.17.21 + marked: 13.0.3 + roughjs: 4.6.6 + stylis: 4.3.4 + ts-dedent: 2.2.0 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mimic-fn@4.0.0: {} + + mimic-function@5.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + mitt@3.0.1: {} + + mlly@1.7.2: + dependencies: + acorn: 8.12.1 + pathe: 1.1.2 + pkg-types: 1.2.1 + ufo: 1.5.4 + + mrmime@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + nanoid@3.3.7: {} + + nanoid@3.3.8: {} + + nanoid@5.0.9: {} + + natural-compare@1.4.0: {} + + neo-async@2.6.2: {} + + node-addon-api@7.1.1: + optional: true + + node-releases@2.0.14: {} + + node-releases@2.0.18: {} + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-inspect@1.13.2: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + oniguruma-to-es@3.1.0: + dependencies: + emoji-regex-xs: 1.0.0 + regex: 6.0.1 + regex-recursion: 6.0.2 + + open@10.1.0: + dependencies: + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@8.2.0: + dependencies: + chalk: 5.3.0 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.0.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@3.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-try@2.2.0: {} + + package-manager-detector@0.2.2: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-ms@4.0.0: {} + + parse5-htmlparser2-tree-adapter@7.0.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.1.2 + + parse5@7.1.2: + dependencies: + entities: 4.5.0 + + path-data-parser@0.1.0: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-type@4.0.0: {} + + path-type@5.0.0: {} + + pathe@1.1.2: {} + + perfect-debounce@1.0.0: {} + + photoswipe@5.4.4: {} + + picocolors@1.0.1: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pify@4.0.1: {} + + pkg-types@1.2.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.2 + pathe: 1.1.2 + + pngjs@5.0.0: {} + + points-on-curve@0.2.0: {} + + points-on-path@0.2.1: + dependencies: + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + + possible-typed-array-names@1.0.0: {} + + postcss-load-config@6.0.1(postcss@8.5.2): + dependencies: + lilconfig: 3.1.2 + optionalDependencies: + postcss: 8.5.2 + + postcss-selector-parser@6.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.4.41: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.1 + + postcss@8.5.2: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier@2.3.2: {} + + pretty-ms@9.0.0: + dependencies: + parse-ms: 4.0.0 + + property-information@6.5.0: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + qrcode@1.5.4: + dependencies: + dijkstrajs: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + queue-microtask@1.2.3: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.1: {} + + rechoir@0.6.2: + dependencies: + resolve: 1.22.8 + + regenerate-unicode-properties@10.1.1: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.14.1: {} + + regenerator-transform@0.15.2: + dependencies: + '@babel/runtime': 7.25.0 + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.0.1: + dependencies: + regex-utilities: 2.3.0 + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + regexpu-core@5.3.2: + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.1 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + + regjsparser@0.9.1: + dependencies: + jsesc: 0.5.0 + + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.14.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + robust-predicates@3.0.2: {} + + rollup@4.34.6: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.34.6 + '@rollup/rollup-android-arm64': 4.34.6 + '@rollup/rollup-darwin-arm64': 4.34.6 + '@rollup/rollup-darwin-x64': 4.34.6 + '@rollup/rollup-freebsd-arm64': 4.34.6 + '@rollup/rollup-freebsd-x64': 4.34.6 + '@rollup/rollup-linux-arm-gnueabihf': 4.34.6 + '@rollup/rollup-linux-arm-musleabihf': 4.34.6 + '@rollup/rollup-linux-arm64-gnu': 4.34.6 + '@rollup/rollup-linux-arm64-musl': 4.34.6 + '@rollup/rollup-linux-loongarch64-gnu': 4.34.6 + '@rollup/rollup-linux-powerpc64le-gnu': 4.34.6 + '@rollup/rollup-linux-riscv64-gnu': 4.34.6 + '@rollup/rollup-linux-s390x-gnu': 4.34.6 + '@rollup/rollup-linux-x64-gnu': 4.34.6 + '@rollup/rollup-linux-x64-musl': 4.34.6 + '@rollup/rollup-win32-arm64-msvc': 4.34.6 + '@rollup/rollup-win32-ia32-msvc': 4.34.6 + '@rollup/rollup-win32-x64-msvc': 4.34.6 + fsevents: 2.3.3 + + roughjs@4.6.6: + dependencies: + hachure-fill: 0.5.2 + path-data-parser: 0.1.0 + points-on-curve: 0.2.0 + points-on-path: 0.2.1 + + run-applescript@7.0.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rw@1.3.3: {} + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safer-buffer@2.1.2: {} + + sass-loader@15.0.0(sass@1.84.0): + dependencies: + neo-async: 2.6.2 + optionalDependencies: + sass: 1.84.0 + + sass@1.84.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.0.3 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.1 + + sax@1.2.4: {} + + sax@1.4.1: {} + + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.6.2: {} + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shelljs@0.8.5: + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + + shiki@2.3.2: + dependencies: + '@shikijs/core': 2.3.2 + '@shikijs/engine-javascript': 2.3.2 + '@shikijs/engine-oniguruma': 2.3.2 + '@shikijs/langs': 2.3.2 + '@shikijs/themes': 2.3.2 + '@shikijs/types': 2.3.2 + '@shikijs/vscode-textmate': 10.0.1 + '@types/hast': 3.0.4 + + shx@0.3.3: + dependencies: + minimist: 1.2.8 + shelljs: 0.8.5 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + signal-exit@4.1.0: {} + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + + sitemap@8.0.0: + dependencies: + '@types/node': 17.0.45 + '@types/sax': 1.2.7 + arg: 5.0.2 + sax: 1.4.1 + + slash@2.0.0: {} + + slash@3.0.0: {} + + slash@5.1.0: {} + + source-map-js@1.2.0: {} + + source-map-js@1.2.1: {} + + source-map-resolve@0.6.0: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + space-separated-tokens@2.0.2: {} + + speakingurl@14.0.1: {} + + sprintf-js@1.0.3: {} + + stdin-discarder@0.2.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-bom-string@1.0.0: {} + + strip-bom@3.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-json-comments@3.1.1: {} + + stylis@4.3.4: {} + + stylus@0.56.0: + dependencies: + css: 3.0.0 + debug: 4.3.5 + glob: 7.2.3 + safer-buffer: 2.1.2 + sax: 1.2.4 + source-map: 0.7.4 + transitivePeerDependencies: + - supports-color + + superjson@2.2.1: + dependencies: + copy-anything: 3.0.5 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-tags@1.0.0: {} + + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.1 + + text-table@0.2.0: {} + + tinyexec@0.3.1: {} + + to-fast-properties@2.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + trim-lines@3.0.1: {} + + ts-api-utils@1.3.0(typescript@5.5.3): + dependencies: + typescript: 5.5.3 + + ts-dedent@2.2.0: {} + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tsconfig-vuepress@4.5.0: {} + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typescript@5.5.3: {} + + uc.micro@2.1.0: {} + + ufo@1.5.4: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + undici@6.21.1: {} + + unicode-canonical-property-names-ecmascript@2.0.0: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + + unicode-match-property-value-ecmascript@2.1.0: {} + + unicode-property-aliases-ecmascript@2.1.0: {} + + unicorn-magic@0.1.0: {} + + unicorn-magic@0.3.0: {} + + unist-util-is@6.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.1: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + + unist-util-visit@5.0.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.0 + unist-util-visit-parents: 6.0.1 + + universalify@2.0.0: {} + + upath@2.0.1: {} + + update-browserslist-db@1.1.0(browserslist@4.23.2): + dependencies: + browserslist: 4.23.2 + escalade: 3.1.2 + picocolors: 1.0.1 + + update-browserslist-db@1.1.0(browserslist@4.23.3): + dependencies: + browserslist: 4.23.3 + escalade: 3.1.2 + picocolors: 1.0.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + uuid@9.0.1: {} + + vfile-message@4.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.2 + + vite-hot-client@0.2.3(vite@6.0.11(sass@1.84.0)(stylus@0.56.0)): + dependencies: + vite: 6.0.11(sass@1.84.0)(stylus@0.56.0) + + vite-plugin-inspect@0.8.5(rollup@4.34.6)(vite@6.0.11(sass@1.84.0)(stylus@0.56.0)): + dependencies: + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.1.0(rollup@4.34.6) + debug: 4.3.5 + error-stack-parser-es: 0.1.5 + fs-extra: 11.2.0 + open: 10.1.0 + perfect-debounce: 1.0.0 + picocolors: 1.0.1 + sirv: 2.0.4 + vite: 6.0.11(sass@1.84.0)(stylus@0.56.0) + transitivePeerDependencies: + - rollup + - supports-color + + vite-plugin-vue-devtools@7.3.8(rollup@4.34.6)(vite@6.0.11(sass@1.84.0)(stylus@0.56.0))(vue@3.4.31(typescript@5.5.3)): + dependencies: + '@vue/devtools-core': 7.3.8(vite@6.0.11(sass@1.84.0)(stylus@0.56.0))(vue@3.4.31(typescript@5.5.3)) + '@vue/devtools-kit': 7.3.8 + '@vue/devtools-shared': 7.3.8 + execa: 8.0.1 + sirv: 2.0.4 + vite: 6.0.11(sass@1.84.0)(stylus@0.56.0) + vite-plugin-inspect: 0.8.5(rollup@4.34.6)(vite@6.0.11(sass@1.84.0)(stylus@0.56.0)) + vite-plugin-vue-inspector: 5.1.3(vite@6.0.11(sass@1.84.0)(stylus@0.56.0)) + transitivePeerDependencies: + - '@nuxt/kit' + - rollup + - supports-color + - vue + + vite-plugin-vue-inspector@5.1.3(vite@6.0.11(sass@1.84.0)(stylus@0.56.0)): + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-proposal-decorators': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.25.2) + '@babel/plugin-transform-typescript': 7.25.2(@babel/core@7.25.2) + '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.25.2) + '@vue/compiler-dom': 3.4.38 + kolorist: 1.8.0 + magic-string: 0.30.10 + vite: 6.0.11(sass@1.84.0)(stylus@0.56.0) + transitivePeerDependencies: + - supports-color + + vite@6.0.11(sass@1.84.0)(stylus@0.56.0): + dependencies: + esbuild: 0.24.2 + postcss: 8.5.2 + rollup: 4.34.6 + optionalDependencies: + fsevents: 2.3.3 + sass: 1.84.0 + stylus: 0.56.0 + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-uri@3.0.8: {} + + vue-demi@0.13.11(vue@3.4.31(typescript@5.5.3)): + dependencies: + vue: 3.4.31(typescript@5.5.3) + + vue-eslint-parser@9.4.3(eslint@8.57.0): + dependencies: + debug: 4.3.5 + eslint: 8.57.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + lodash: 4.17.21 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + + vue-router@4.4.0(vue@3.4.31(typescript@5.5.3)): + dependencies: + '@vue/devtools-api': 6.6.3 + vue: 3.4.31(typescript@5.5.3) + + vue-router@4.5.0(vue@3.5.13(typescript@5.5.3)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.13(typescript@5.5.3) + + vue@3.4.31(typescript@5.5.3): + dependencies: + '@vue/compiler-dom': 3.4.31 + '@vue/compiler-sfc': 3.4.31 + '@vue/runtime-dom': 3.4.31 + '@vue/server-renderer': 3.4.31(vue@3.4.31(typescript@5.5.3)) + '@vue/shared': 3.4.31 + optionalDependencies: + typescript: 5.5.3 + + vue@3.5.13(typescript@5.5.3): + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.5.3)) + '@vue/shared': 3.5.13 + optionalDependencies: + typescript: 5.5.3 + + vuepress-plugin-components@2.0.0-rc.71(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))): + dependencies: + '@stackblitz/sdk': 1.11.0 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-sass-palette': 2.0.0-rc.74(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + balloon-css: 1.2.0 + create-codepen: 2.0.0 + qrcode: 1.5.4 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + vuepress-shared: 2.0.0-rc.71(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + optionalDependencies: + sass: 1.84.0 + sass-loader: 15.0.0(sass@1.84.0) + transitivePeerDependencies: + - typescript + + vuepress-plugin-md-enhance@2.0.0-rc.71(markdown-it@14.1.0)(mermaid@11.3.0)(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))): + dependencies: + '@mdit/plugin-container': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-demo': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-plantuml': 0.16.0(markdown-it@14.1.0) + '@mdit/plugin-uml': 0.16.0(markdown-it@14.1.0) + '@types/markdown-it': 14.1.2 + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-sass-palette': 2.0.0-rc.74(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + balloon-css: 1.2.0 + js-yaml: 4.1.0 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + vuepress-shared: 2.0.0-rc.71(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + optionalDependencies: + mermaid: 11.3.0 + sass: 1.84.0 + sass-loader: 15.0.0(sass@1.84.0) + transitivePeerDependencies: + - markdown-it + - typescript + + vuepress-shared@2.0.0-rc.71(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))): + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + dayjs: 1.11.13 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + transitivePeerDependencies: + - typescript + + vuepress-theme-hope@2.0.0-rc.71(@vuepress/plugin-search@2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))))(katex@0.16.11)(markdown-it@14.1.0)(mermaid@11.3.0)(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))): + dependencies: + '@vuepress/helper': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-active-header-links': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-back-to-top': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-blog': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-catalog': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-comment': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-copy-code': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-copyright': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-git': 2.0.0-rc.68(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-icon': 2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-links-check': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-markdown-ext': 2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-markdown-hint': 2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-markdown-image': 2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-markdown-include': 2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-markdown-math': 2.0.0-rc.74(katex@0.16.11)(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-markdown-stylize': 2.0.0-rc.75(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-markdown-tab': 2.0.0-rc.74(markdown-it@14.1.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-notice': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-nprogress': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-photo-swipe': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-reading-time': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-redirect': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-rtl': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-sass-palette': 2.0.0-rc.74(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-seo': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-shiki': 2.0.0-rc.74(@vueuse/core@12.5.0(typescript@5.5.3))(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-sitemap': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vuepress/plugin-theme-data': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + '@vueuse/core': 12.5.0(typescript@5.5.3) + balloon-css: 1.2.0 + bcrypt-ts: 5.0.3 + chokidar: 3.6.0 + vue: 3.5.13(typescript@5.5.3) + vuepress: 2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)) + vuepress-plugin-components: 2.0.0-rc.71(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vuepress-plugin-md-enhance: 2.0.0-rc.71(markdown-it@14.1.0)(mermaid@11.3.0)(sass-loader@15.0.0(sass@1.84.0))(sass@1.84.0)(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + vuepress-shared: 2.0.0-rc.71(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + optionalDependencies: + '@vuepress/plugin-search': 2.0.0-rc.74(typescript@5.5.3)(vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3))) + sass: 1.84.0 + sass-loader: 15.0.0(sass@1.84.0) + transitivePeerDependencies: + - '@vue/repl' + - '@waline/client' + - artalk + - artplayer + - chart.js + - dashjs + - echarts + - flowchart.ts + - hls.js + - katex + - kotlin-playground + - markdown-it + - markmap-lib + - markmap-toolbar + - markmap-view + - mathjax-full + - mermaid + - mpegts.js + - sandpack-vue3 + - twikoo + - typescript + - vidstack + + vuepress@2.0.0-rc.19(@vuepress/bundler-vite@2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3))(typescript@5.5.3)(vue@3.4.31(typescript@5.5.3)): + dependencies: + '@vuepress/cli': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/client': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/core': 2.0.0-rc.19(typescript@5.5.3) + '@vuepress/markdown': 2.0.0-rc.19 + '@vuepress/shared': 2.0.0-rc.19 + '@vuepress/utils': 2.0.0-rc.19 + vue: 3.4.31(typescript@5.5.3) + optionalDependencies: + '@vuepress/bundler-vite': 2.0.0-rc.19(sass@1.84.0)(stylus@0.56.0)(typescript@5.5.3) + transitivePeerDependencies: + - supports-color + - typescript + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-module@2.0.1: {} + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + xml-name-validator@4.0.0: {} + + y18n@4.0.3: {} + + yallist@3.1.1: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + yocto-queue@0.1.0: {} + + yoctocolors@2.1.1: {} + + zwitch@2.0.4: {} diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 00000000..c9c18893 --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "tsconfig-vuepress/base.json", + "compilerOptions": { + "lib": ["DOM", "ES2022"], + "module": "ESNext", + "moduleResolution": "Bundler", + "target": "ES2022", + "declaration": false, + "allowJs": true + }, + "include": ["**/.vuepress/**/*"], + "exclude": ["node_modules", ".cache", ".temp", "dist"] +} \ No newline at end of file From 30f6567a931aea56a42469293b7f174072526077 Mon Sep 17 00:00:00 2001 From: William Chong Date: Wed, 23 Jul 2025 12:02:53 +0400 Subject: [PATCH 11/18] Adapt docs for kurrentdb --- docs/api/appending-events.md | 36 +++++++++--------- docs/api/authentication.md | 10 ++--- docs/api/delete-stream.md | 10 ++--- docs/api/getting-started.md | 56 ++++++++++++++-------------- docs/api/observability.md | 14 +++---- docs/api/persistent-subscriptions.md | 6 +-- docs/api/projections.md | 10 ++--- docs/api/reading-events.md | 14 +++---- docs/api/subscriptions.md | 10 ++--- 9 files changed, 84 insertions(+), 82 deletions(-) diff --git a/docs/api/appending-events.md b/docs/api/appending-events.md index 89846655..f471a71d 100644 --- a/docs/api/appending-events.md +++ b/docs/api/appending-events.md @@ -4,7 +4,7 @@ order: 2 # Appending events -When you start working with EventStoreDB, your application streams are empty. The first meaningful operation is to add one or more events to the database using this API. +When you start working with KurrentDB, your application streams are empty. The first meaningful operation is to add one or more events to the database using this API. ::: tip Check the [Getting Started](getting-started.md) guide to learn how to configure and use the client SDK. @@ -12,7 +12,7 @@ Check the [Getting Started](getting-started.md) guide to learn how to configure ## Append your first event -The simplest way to append an event to EventStoreDB is to create an `EventData` object and call `appendToStream` method. +The simplest way to append an event to KurrentDB is to create an `EventData` object and call `appendToStream` method. ```java {32-43} class OrderPlaced { @@ -54,7 +54,7 @@ EventData eventData = EventData .build(); AppendToStreamOptions options = AppendToStreamOptions.get() - .expectedRevision(ExpectedRevision.noStream()); + .streamState(StreamState.noStream()); client.appendToStream("orders", options, eventData) .get(); @@ -71,11 +71,11 @@ If you are new to Event Sourcing, please study the [Handling concurrency](#handl ## Working with EventData -Events appended to EventStoreDB must be wrapped in an `EventData` object. This allows you to specify the event's content, the type of event, and whether it's in JSON format. In its simplest form, you need three arguments: **eventId**, **eventType**, and **eventData**. +Events appended to KurrentDB must be wrapped in an `EventData` object. This allows you to specify the event's content, the type of event, and whether it's in JSON format. In its simplest form, you need three arguments: **eventId**, **eventType**, and **eventData**. ### eventId -This takes the format of a `UUID` and is used to uniquely identify the event you are trying to append. If two events with the same `UUID` are appended to the same stream in quick succession, EventStoreDB will only append one of the events to the stream. +This takes the format of a `UUID` and is used to uniquely identify the event you are trying to append. If two events with the same `UUID` are appended to the same stream in quick succession, KurrentDB will only append one of the events to the stream. For example, the following code will only append a single event: @@ -88,7 +88,7 @@ EventData eventData = EventData .build(); AppendToStreamOptions options = AppendToStreamOptions.get() - .expectedRevision(ExpectedRevision.any()); + .streamState(StreamState.any()); client.appendToStream("orders", options, eventData) .get(); @@ -106,11 +106,11 @@ It is common to see the explicit event code type name used as the type as it mak ### eventData -Representation of your event data. It is recommended that you store your events as JSON objects. This allows you to take advantage of all of EventStoreDB's functionality, such as projections. That said, you can save events using whatever format suits your workflow. Eventually, the data will be stored as encoded bytes. +Representation of your event data. It is recommended that you store your events as JSON objects. This allows you to take advantage of all of KurrentDB's functionality, such as projections. That said, you can save events using whatever format suits your workflow. Eventually, the data will be stored as encoded bytes. ### userMetadata -Storing additional information alongside your event that is part of the event itself is standard practice. This can be correlation IDs, timestamps, access information, etc. EventStoreDB allows you to store a separate byte array containing this information to keep it separate. +Storing additional information alongside your event that is part of the event itself is standard practice. This can be correlation IDs, timestamps, access information, etc. KurrentDB allows you to store a separate byte array containing this information to keep it separate. ### contentType @@ -118,7 +118,7 @@ The content type indicates whether the event is stored as JSON or binary format. ## Handling concurrency -When appending events to a stream, you can supply an *expected revision*. Your client uses this to inform EventStoreDB of the state or version you expect the stream to be in when appending an event. If the stream isn't in that state, an exception will be thrown. +When appending events to a stream, you can supply a *stream state*. Your client uses this to inform KurrentDB of the state or version you expect the stream to be in when appending an event. If the stream isn't in that state, an exception will be thrown. For example, if you try to append the same record twice, expecting both times that the stream doesn't exist, you will get an exception on the second: @@ -138,7 +138,7 @@ EventData eventDataTwo = EventData .build(); AppendToStreamOptions options = AppendToStreamOptions.get() - .expectedRevision(ExpectedRevision.noStream()); + .streamState(StreamState.noStream()); client.appendToStream("no-stream-stream", options, eventDataOne) .get(); @@ -149,12 +149,14 @@ client.appendToStream("no-stream-stream", options, eventDataTwo) ``` There are several available expected revision options: -- `ExpectedRevision.any()` - No concurrency check -- `ExpectedRevision.noStream()` - Stream should not exist -- `ExpectedRevision.streamExists()` - Stream should exist -- `ExpectedRevision.expectedRevision(long revision)` - Stream should be at specific revision +- `StreamState.any()` - No concurrency check +- `StreamState.noStream()` - Stream should not exist +- `StreamState.streamExists()` - Stream should exist +- `StreamState.streamRevision(long revision)` - Stream should be at specific revision -This check can be used to implement optimistic concurrency. When retrieving a stream from EventStoreDB, note the current version number. When you save it back, you can determine if somebody else has modified the record in the meantime. +This check can be used to implement optimistic concurrency. When retrieving a +stream from KurrentDB, note the current version number. When you save it back, +you can determine if somebody else has modified the record in the meantime. First, let's define the event classes for our ecommerce example: @@ -218,14 +220,14 @@ EventData orderCancelledEvent = EventData // Process payment (succeeds) AppendToStreamOptions appendOptions = AppendToStreamOptions.get() - .streamRevision(currentRevision); + .streamState(currentRevision); WriteResult paymentResult = client.appendToStream("order-12345", appendOptions, paymentProcessedEvent) .get(); // Cancel order (fails due to concurrency conflict) AppendToStreamOptions cancelOptions = AppendToStreamOptions.get() - .streamRevision(currentRevision); + .streamState(currentRevision); client.appendToStream("order-12345", cancelOptions, orderCancelledEvent) .get(); diff --git a/docs/api/authentication.md b/docs/api/authentication.md index 521cebbc..b6b89ff1 100644 --- a/docs/api/authentication.md +++ b/docs/api/authentication.md @@ -4,7 +4,7 @@ order: 7 head: - - title - {} - - Authentication | Java | Clients | EventStore Docs + - Authentication | Java | Clients | Kurrent Docs --- # Client x.509 certificate @@ -15,7 +15,7 @@ X.509 certificates are digital certificates that use the X.509 public key infras ## Prerequisites -1. KurrentDB 25.0 or greater, or EventStoreDB 24.10 or later. +1. KurrentDB 25.0 or greater, or KurrentDB 24.10 or later. 2. A valid X.509 certificate configured on the Database. See [configuration steps](@server/security/user-authentication.html#user-x-509-certificates) for more details. ## Connect using an x.509 certificate @@ -36,8 +36,8 @@ The client supports the following parameters: To authenticate, include these two parameters in your connection string or constructor when initializing the client: ```java -EventStoreDBClientSettings settings = EventStoreDBConnectionString - .parseOrThrow("esdb://admin:changeit@{endpoint}?tls=true&userCertFile={pathToCaFile}&userKeyFile={pathToKeyFile}"); +KurrentDBClientSettings settings = KurrentDBConnectionString + .parseOrThrow("kurrentdb://admin:changeit@{endpoint}?tls=true&userCertFile={pathToCaFile}&userKeyFile={pathToKeyFile}"); -EventStoreDBClient client = EventStoreDBClient.create(settings); +KurrentDBClient client = KurrentDBClient.create(settings); ``` \ No newline at end of file diff --git a/docs/api/delete-stream.md b/docs/api/delete-stream.md index 262c70af..659be696 100644 --- a/docs/api/delete-stream.md +++ b/docs/api/delete-stream.md @@ -3,20 +3,20 @@ order: 9 head: - - title - {} - - Deleting Events | Java | Clients | EventStore Docs + - Deleting Events | Java | Clients | Kurrent Docs --- # Deleting Events -In EventStoreDB, you can delete events and streams either partially or +In KurrentDB, you can delete events and streams either partially or completely. Settings like $maxAge and $maxCount help control how long events are kept or how many events are stored in a stream, but they won't delete the entire -stream. When you need to fully remove a stream, EventStoreDB offers two +stream. When you need to fully remove a stream, KurrentDB offers two options: Soft Delete and Hard Delete. ## Soft delete -Soft delete in EventStoreDB allows you to mark a stream for deletion without +Soft delete in KurrentDB allows you to mark a stream for deletion without completely removing it, so you can still add new events later. While you can do this through the UI, using code is often better for automating the process, handling many streams at once, or including custom rules. Code is especially @@ -36,7 +36,7 @@ process. The stream can still be reopened by appending new events. ## Hard delete -Hard delete in EventStoreDB permanently removes a stream and its events. While +Hard delete in KurrentDB permanently removes a stream and its events. While you can use the HTTP API, code is often better for automating the process, managing multiple streams, and ensuring precise control. Code is especially useful when you need to integrate hard delete into larger workflows or apply diff --git a/docs/api/getting-started.md b/docs/api/getting-started.md index a6e5771a..03f9d473 100644 --- a/docs/api/getting-started.md +++ b/docs/api/getting-started.md @@ -3,63 +3,63 @@ order: 1 head: - - title - {} - - Getting Started | Java | Clients | EventStoreDB Docs + - Getting Started | Java | Clients | KurrentDB Docs --- # Getting started -This guide will help you get started with EventStoreDB in your Java application. -It covers the basic steps to connect to EventStoreDB, create events, append them +This guide will help you get started with KurrentDB in your Java application. +It covers the basic steps to connect to KurrentDB, create events, append them to streams, and read them back. ## Required packages -Add the `db-client-java` dependency to your project: +Add the `kurrentdb-client` dependency to your project: ::: tabs @tab gradle -```bash -implementation 'com.eventstore:db-client-java:5.4.x' +```groovy +implementation 'io.kurrent:kurrentdb-client:1.0.x' ``` @tab maven -```bash +```xml - com.eventstore - db-client-java - 5.4.x + io.kurrent + kurrentdb-client + 1.0.x ``` ::: -## Connecting to EventStoreDB +## Connecting to KurrentDB -To connect your application to EventStoreDB, you need to configure and create a client instance. +To connect your application to KurrentDB, you need to configure and create a client instance. ::: tip Insecure clusters -The recommended way to connect to EventStoreDB is using secure mode (which is -the default). However, if your EventStoreDB instance is running in insecure +The recommended way to connect to KurrentDB is using secure mode (which is +the default). However, if your KurrentDB instance is running in insecure mode, you must explicitly set `tls=false` in your [connection string](#connection-string) or client configuration. ::: -EventStoreDB uses connection strings to configure the client connection. The connection string supports two protocols: +KurrentDB uses connection strings to configure the client connection. The connection string supports two protocols: -- **`esdb://`** - for connecting directly to specific node endpoints (single node or multi-node cluster with explicit endpoints) -- **`esdb+discover://`** - for connecting using cluster discovery via DNS or gossip endpoints +- **`kurrentdb://`** - for connecting directly to specific node endpoints (single node or multi-node cluster with explicit endpoints) +- **`kurrentdb+discover://`** - for connecting using cluster discovery via DNS or gossip endpoints -When using `esdb://`, you specify the exact endpoints to connect to. The client will connect directly to these endpoints. For multi-node clusters, you can specify multiple endpoints separated by commas, and the client will query each node's Gossip API to get cluster information, then picks a node based on the URI's node preference. +When using `kurrentdb://`, you specify the exact endpoints to connect to. The client will connect directly to these endpoints. For multi-node clusters, you can specify multiple endpoints separated by commas, and the client will query each node's Gossip API to get cluster information, then picks a node based on the URI's node preference. -With `esdb+discover://`, the client uses cluster discovery to find available nodes. This is particularly useful when you have a DNS A record pointing to cluster nodes or when you want the client to automatically discover the cluster topology. +With `kurrentdb+discover://`, the client uses cluster discovery to find available nodes. This is particularly useful when you have a DNS A record pointing to cluster nodes or when you want the client to automatically discover the cluster topology. ::: info Gossip support -Since version 22.10, EventStoreDB supports gossip on single-node deployments, so -`esdb+discover://` can be used for any topology, including single-node setups. +Since version 22.10, KurrentDB supports gossip on single-node deployments, so +`kurrentdb+discover://` can be used for any topology, including single-node setups. ::: For cluster connections using discovery, use the following format: ``` -esdb+discover://admin:changeit@cluster.dns.name:2113 +kurrentdb+discover://admin:changeit@cluster.dns.name:2113 ``` Where `cluster.dns.name` is a DNS `A` record that points to all cluster nodes. @@ -67,13 +67,13 @@ Where `cluster.dns.name` is a DNS `A` record that points to all cluster nodes. For direct connections to specific endpoints, you can specify individual nodes: ``` -esdb://admin:changeit@node1.dns.name:2113,node2.dns.name:2113,node3.dns.name:2113 +kurrentdb://admin:changeit@node1.dns.name:2113,node2.dns.name:2113,node3.dns.name:2113 ``` Or for a single node: ``` -esdb://admin:changeit@localhost:2113 +kurrentdb://admin:changeit@localhost:2113 ``` There are a number of query parameters that can be used in the connection string to instruct the cluster how and where the connection should be established. All query parameters are optional. @@ -96,22 +96,22 @@ There are a number of query parameters that can be used in the connection string | `dnsDiscover` | `true`, `false` | `false` | Enable DNS-based cluster discovery. When `true`, resolves hostnames to discover cluster nodes. Use with `feature=dns-lookup` for full DNS resolution. | | `feature` | `dns-lookup` | None | Enable specific client features. Use `dns-lookup` with `dnsDiscover=true` to resolve hostnames to multiple IP addresses for cluster discovery. | -When connecting to an insecure instance, specify `tls=false` parameter. For example, for a node running locally use `esdb://localhost:2113?tls=false`. Note that usernames and passwords aren't provided there because insecure deployments don't support authentication and authorisation. +When connecting to an insecure instance, specify `tls=false` parameter. For example, for a node running locally use `kurrentdb://localhost:2113?tls=false`. Note that usernames and passwords aren't provided there because insecure deployments don't support authentication and authorisation. ## Creating a client First, create a client and get it connected to the database. ```java -EventStoreDBClientSettings settings = EventStoreDBConnectionString.parseOrThrow("esdb://localhost:2113?tls=false"); -EventStoreDBClient client = EventStoreDBClient.create(settings); +KurrentDBClientSettings settings = KurrentDBConnectionString.parseOrThrow("kurrentdb://localhost:2113?tls=false"); +KurrentDBClient client = KurrentDBClient.create(settings); ``` The client instance can be used as a singleton across the whole application. It doesn't need to open or close the connection. ## Creating an event -You can write anything to EventStoreDB as events. The client needs a byte array as the event payload. Normally, you'd use a serialized object, and it's up to you to choose the serialization method. +You can write anything to KurrentDB as events. The client needs a byte array as the event payload. Normally, you'd use a serialized object, and it's up to you to choose the serialization method. The code snippet below creates an event object instance, serializes it, and adds it as a payload to the `EventData` structure, which the client can then write to the database. diff --git a/docs/api/observability.md b/docs/api/observability.md index e7c33568..a216fd21 100644 --- a/docs/api/observability.md +++ b/docs/api/observability.md @@ -3,7 +3,7 @@ order: 8 head: - - title - {} - - Observability | Java | Clients | EventStore Docs + - Observability | Java | Clients | Kurrent Docs --- # Observability @@ -97,10 +97,10 @@ public class EventStoreObservability { .setTracerProvider(sdkTracerProvider) .buildAndRegisterGlobal(); - // Your EventStoreDB client operations will now be traced - EventStoreDBClientSettings settings = EventStoreDBConnectionString - .parseOrThrow("esdb://localhost:2113?tls=false"); - EventStoreDBClient client = EventStoreDBClient.create(settings); + // Your KurrentDB client operations will now be traced + KurrentDBClientSettings settings = KurrentDBConnectionString + .parseOrThrow("kurrentdb://localhost:2113?tls=false"); + KurrentDBClient client = KurrentDBClient.create(settings); } } ``` @@ -175,8 +175,8 @@ Each trace includes metadata to help with debugging and monitoring: | `db.eventstoredb.subscription.id` | Subscription identifier | `user-events-123-sub` | | `db.eventstoredb.event.id` | Event identifier | `event-456` | | `db.eventstoredb.event.type` | Event type identifier | `user.created` | -| `server.address` | EventStoreDB server address | `localhost` | -| `server.port` | EventStoreDB server port | `2113` | +| `server.address` | KurrentDB server address | `localhost` | +| `server.port` | KurrentDB server port | `2113` | | `exception.type` | Exception type if an error occurred | | | `exception.message` | Exception message if an error occurred | | | `exception.stacktrace` | Stack trace of the exception | | diff --git a/docs/api/persistent-subscriptions.md b/docs/api/persistent-subscriptions.md index 244ac6a1..7143ea27 100644 --- a/docs/api/persistent-subscriptions.md +++ b/docs/api/persistent-subscriptions.md @@ -3,7 +3,7 @@ order: 5 head: - - title - {} - - Persistent Subscriptions | Java | Clients | EventStore Docs + - Persistent Subscriptions | Java | Clients | Kurrent Docs --- # Persistent Subscriptions @@ -29,7 +29,7 @@ You can read more about persistent subscriptions in the [server documentation](@ The Java client provides a `PersistentSubscriptionsClient` that you can use to manage persistent subscriptions. ```java -EventStoreDBClientSettings settings = EventStoreDBConnectionString.parseOrThrow("esdb://localhost:2113?tls=false"); +KurrentDBClientSettings settings = KurrentDBConnectionString.parseOrThrow("kurrentdb://localhost:2113?tls=false"); PersistentSubscriptionsClient client = PersistentSubscriptionsClient.create(settings); ``` @@ -212,7 +212,7 @@ resources. For use with an indexing projection such as the system `$by_category` projection. -EventStoreDB inspects the event for its source stream id, hashing the id to one +KurrentDB inspects the event for its source stream id, hashing the id to one of 1024 buckets assigned to individual clients. When a client disconnects, its buckets are assigned to other clients. When a client connects, it is assigned some existing buckets. This naively attempts to maintain a balanced workload. diff --git a/docs/api/projections.md b/docs/api/projections.md index 6afd23a5..18e4072a 100644 --- a/docs/api/projections.md +++ b/docs/api/projections.md @@ -4,22 +4,22 @@ title: Projections head: - - title - {} - - Projections | Java | Clients | EventStore Docs + - Projections | Java | Clients | Kurrent Docs --- # Projection management -The client provides a way to manage projections in EventStoreDB. +The client provides a way to manage projections in KurrentDB. For a detailed explanation of projections, see the [server documentation](@server/features/projections/README.md). ## Creating a client -The Java client provides a `EventStoreDBProjectionManagementClient` that you can use to manage persistent subscriptions. +The Java client provides a `KurrentDBProjectionManagementClient` that you can use to manage persistent subscriptions. ```java -EventStoreDBClientSettings settings = EventStoreDBConnectionString.parseOrThrow("esdb://localhost:2113?tls=false"); -EventStoreDBProjectionManagementClient client = EventStoreDBProjectionManagementClient.create(settings); +KurrentDBClientSettings settings = KurrentDBConnectionString.parseOrThrow("kurrentdb://localhost:2113?tls=false"); +KurrentDBProjectionManagementClient client = KurrentDBProjectionManagementClient.create(settings); ``` ## Create a projection diff --git a/docs/api/reading-events.md b/docs/api/reading-events.md index 8216ffc1..c5ed67d3 100644 --- a/docs/api/reading-events.md +++ b/docs/api/reading-events.md @@ -3,21 +3,21 @@ order: 3 head: - - title - {} - - Reading Events | Java | Clients | EventStore Docs + - Reading Events | Java | Clients | Kurrent Docs --- # Reading Events -EventStoreDB provides two primary methods for reading events: reading from an +KurrentDB provides two primary methods for reading events: reading from an individual stream to retrieve events from a specific named stream, or reading from the `$all` stream to access all events across the entire event store. -Events in EventStoreDB are organized within individual streams and use two +Events in KurrentDB are organized within individual streams and use two distinct positioning systems to track their location. The **revision number** is a 64-bit signed integer (`long`) that represents the sequential position of an event within its specific stream. Events are numbered starting from 0, with each new event receiving the next sequential revision number (0, 1, 2, 3...). The -**global position** represents the event's location in EventStoreDB's global +**global position** represents the event's location in KurrentDB's global transaction log and consists of two coordinates: the `commit` position (where the transaction was committed in the log) and the `prepare` position (where the transaction was initially prepared). @@ -92,7 +92,7 @@ ReadStreamOptions options = ReadStreamOptions.get() #### resolveLinkTos -When using projections to create new events you can set whether the generated events are pointers to existing events. Setting this value to true will tell EventStoreDB to return the event as well as the event linking to it. +When using projections to create new events you can set whether the generated events are pointers to existing events. Setting this value to true will tell KurrentDB to return the event as well as the event linking to it. ```java{4} ReadStreamOptions options = ReadStreamOptions.get() @@ -233,7 +233,7 @@ ReadAllOptions options = ReadAllOptions.get() #### resolveLinkTos -When using projections to create new events you can set whether the generated events are pointers to existing events. Setting this value to true will tell EventStoreDB to return the event as well as the event linking to it. +When using projections to create new events you can set whether the generated events are pointers to existing events. Setting this value to true will tell KurrentDB to return the event as well as the event linking to it. ```java{4} ReadAllOptions options = ReadAllOptions.get() @@ -278,7 +278,7 @@ Read one event backwards to find the last position in the `$all` stream. ### Handling system events -EventStoreDB will also return system events when reading from the `$all` stream. In most cases you can ignore these events. +KurrentDB will also return system events when reading from the `$all` stream. In most cases you can ignore these events. All system events begin with `$` or `$$` and can be easily ignored by checking the `eventType` property. diff --git a/docs/api/subscriptions.md b/docs/api/subscriptions.md index df4b2832..eca18b9d 100644 --- a/docs/api/subscriptions.md +++ b/docs/api/subscriptions.md @@ -3,7 +3,7 @@ order: 4 head: - - title - {} - - Catch-up Subscriptions | Java | Clients | EventStore Docs + - Catch-up Subscriptions | Java | Clients | Kurrent Docs --- # Catch-up Subscriptions @@ -102,7 +102,7 @@ client.subscribeToAll( ## Resolving link-to events -Link-to events point to events in other streams in EventStoreDB. These are +Link-to events point to events in other streams in KurrentDB. These are generally created by projections such as the `$by_event_type` projection which links events of the same event type into the same stream. This makes it easier to look up all events of a specific type. @@ -205,8 +205,8 @@ client.subscribeToAll( ## Handling Subscription State Changes -::: info EventStoreDB 23.10.0+ -This feature requires EventStoreDB version 23.10.0 or later. +::: info KurrentDB 23.10.0+ +This feature requires KurrentDB version 23.10.0 or later. ::: When a subscription processes historical events and reaches the end of the @@ -265,7 +265,7 @@ client.subscribeToAll(listener, options); ## Server-side Filtering -EventStoreDB allows you to filter events while subscribing to the `$all` stream to only receive the events you care about. You can filter by event type or stream name using a regular expression or a prefix. Server-side filtering is currently only available on the `$all` stream. +KurrentDB allows you to filter events while subscribing to the `$all` stream to only receive the events you care about. You can filter by event type or stream name using a regular expression or a prefix. Server-side filtering is currently only available on the `$all` stream. ::: tip Server-side filtering was introduced as a simpler alternative to projections. You should consider filtering before creating a projection to include the events you care about. From 5516bcff44f4bc08febcf15e372a8de63d8eef84 Mon Sep 17 00:00:00 2001 From: William Chong Date: Wed, 23 Jul 2025 15:50:09 +0400 Subject: [PATCH 12/18] docs: remove dns discover --- docs/api/getting-started.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/api/getting-started.md b/docs/api/getting-started.md index 03f9d473..55311992 100644 --- a/docs/api/getting-started.md +++ b/docs/api/getting-started.md @@ -38,8 +38,8 @@ To connect your application to KurrentDB, you need to configure and create a cli ::: tip Insecure clusters The recommended way to connect to KurrentDB is using secure mode (which is the default). However, if your KurrentDB instance is running in insecure -mode, you must explicitly set `tls=false` in your [connection -string](#connection-string) or client configuration. +mode, you must explicitly set `tls=false` in your connection +string or client configuration. ::: KurrentDB uses connection strings to configure the client connection. The connection string supports two protocols: @@ -93,7 +93,6 @@ There are a number of query parameters that can be used in the connection string | `keepAliveTimeout` | Number | `10` | Keep-alive ping call timeout, in seconds. | | `userCertFile` | String, file path | None | User certificate file for X.509 authentication. | | `userKeyFile` | String, file path | None | Key file for the user certificate used for X.509 authentication. | -| `dnsDiscover` | `true`, `false` | `false` | Enable DNS-based cluster discovery. When `true`, resolves hostnames to discover cluster nodes. Use with `feature=dns-lookup` for full DNS resolution. | | `feature` | `dns-lookup` | None | Enable specific client features. Use `dns-lookup` with `dnsDiscover=true` to resolve hostnames to multiple IP addresses for cluster discovery. | When connecting to an insecure instance, specify `tls=false` parameter. For example, for a node running locally use `kurrentdb://localhost:2113?tls=false`. Note that usernames and passwords aren't provided there because insecure deployments don't support authentication and authorisation. @@ -218,4 +217,4 @@ latch.await(); When you read events from the stream, you get a collection of `ResolvedEvent` structures (synchronous) or `ReadMessage` objects (reactive). The event payload is returned as a byte array and needs to be deserialized. See more advanced -scenarios in [reading events documentation](./reading-events.md). \ No newline at end of file +scenarios in [reading events documentation](./reading-events.md). From b2052b1cf5005e0b39ae401ecd7020813c995936 Mon Sep 17 00:00:00 2001 From: William Chong Date: Fri, 25 Jul 2025 11:00:08 +0400 Subject: [PATCH 13/18] Fix CI (#336) --- .github/workflows/ci.yml | 4 ++++ .github/workflows/lts.yml | 4 ++++ .github/workflows/previous-lts.yml | 4 ++++ .github/workflows/tests.yml | 6 ------ 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5a4d4f68..227acc49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,10 @@ name: CI on: pull_request: + paths-ignore: + - "docs/**" + - "samples/**" + - "**.md" push: branches: - trunk diff --git a/.github/workflows/lts.yml b/.github/workflows/lts.yml index 4b1fc04b..3c8fb250 100644 --- a/.github/workflows/lts.yml +++ b/.github/workflows/lts.yml @@ -1,6 +1,10 @@ name: LTS on: pull_request: + paths-ignore: + - "docs/**" + - "samples/**" + - "**.md" push: branches: - trunk diff --git a/.github/workflows/previous-lts.yml b/.github/workflows/previous-lts.yml index f1941397..df1d75e7 100644 --- a/.github/workflows/previous-lts.yml +++ b/.github/workflows/previous-lts.yml @@ -1,6 +1,10 @@ name: Previous LTS on: pull_request: + paths-ignore: + - "docs/**" + - "samples/**" + - "**.md" push: branches: - trunk diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 366e3fec..92ce26e8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,12 +1,6 @@ name: tests workflow on: - pull_request: - paths-ignore: - - "docs/**" - - "samples/**" - - "**.md" - workflow_call: inputs: runtime: From d6155eb7a1c4161071650679c7934090661cc682 Mon Sep 17 00:00:00 2001 From: William Chong Date: Mon, 4 Aug 2025 09:54:37 +0400 Subject: [PATCH 14/18] Take control of the metadata (#337) --- .../kurrent/dbclient/DynamicValueMapper.java | 120 +++++++++++ .../java/io/kurrent/dbclient/EventData.java | 1 + .../io/kurrent/dbclient/EventDataBuilder.java | 3 - .../io/kurrent/dbclient/KurrentDBClient.java | 2 +- .../kurrent/dbclient/MultiStreamAppend.java | 28 ++- .../dbclient/MultiStreamAppendTests.java | 200 ++++++++++++++++-- 6 files changed, 327 insertions(+), 27 deletions(-) create mode 100644 src/main/java/io/kurrent/dbclient/DynamicValueMapper.java diff --git a/src/main/java/io/kurrent/dbclient/DynamicValueMapper.java b/src/main/java/io/kurrent/dbclient/DynamicValueMapper.java new file mode 100644 index 00000000..af4415bf --- /dev/null +++ b/src/main/java/io/kurrent/dbclient/DynamicValueMapper.java @@ -0,0 +1,120 @@ +package io.kurrent.dbclient; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.json.JsonMapper; +import com.google.protobuf.ByteString; +import com.google.protobuf.Timestamp; +import com.google.protobuf.Duration; +import io.kurrentdb.protocol.DynamicValue; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZonedDateTime; +import java.util.Collections; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Utility class for converting Java objects to DynamicValue protobuf messages. + */ +public class DynamicValueMapper { + private static final JsonMapper objectMapper = new JsonMapper(); + + /** + * Converts JSON byte array metadata to a Map of DynamicValue objects. + * + * @param jsonMetadata the source metadata as JSON bytes + * @return a map with DynamicValue objects + */ + public static Map mapJsonToDynamicValueMap(byte[] jsonMetadata) { + if (jsonMetadata == null || jsonMetadata.length == 0) + return Collections.emptyMap(); + + try { + Map metadata = objectMapper.readValue(jsonMetadata, new TypeReference>() { + }); + return mapToDynamicValueMap(metadata); + } catch (Exception e) { + return Collections.emptyMap(); + } + } + + /** + * Converts a Map of metadata to a Map of DynamicValue objects. + * + * @param metadata the source metadata map + * @return a map with DynamicValue objects + */ + public static Map mapToDynamicValueMap(Map metadata) { + if (metadata == null) { + return Collections.emptyMap(); + } + + return metadata.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> mapToDynamicValue(entry.getValue()) + )); + } + + /** + * Converts a Java object to a DynamicValue protobuf message. + * + * @param source the source object + * @return the corresponding DynamicValue + */ + public static DynamicValue mapToDynamicValue(Object source) { + if (source == null) { + return DynamicValue.newBuilder() + .setNullValue(com.google.protobuf.NullValue.NULL_VALUE) + .build(); + } + + DynamicValue.Builder builder = DynamicValue.newBuilder(); + + if (source instanceof String) { + return builder.setStringValue((String) source).build(); + } else if (source instanceof Boolean) { + return builder.setBooleanValue((Boolean) source).build(); + } else if (source instanceof Integer) { + return builder.setInt32Value((Integer) source).build(); + } else if (source instanceof Long) { + return builder.setInt64Value((Long) source).build(); + } else if (source instanceof Float) { + return builder.setFloatValue((Float) source).build(); + } else if (source instanceof Double) { + return builder.setDoubleValue((Double) source).build(); + } else if (source instanceof Instant) { + Instant instant = (Instant) source; + return builder.setTimestampValue(Timestamp.newBuilder() + .setSeconds(instant.getEpochSecond()) + .setNanos(instant.getNano()) + .build()).build(); + } else if (source instanceof LocalDateTime) { + LocalDateTime localDateTime = (LocalDateTime) source; + Instant instant = localDateTime.atZone(java.time.ZoneOffset.UTC).toInstant(); + return builder.setTimestampValue(Timestamp.newBuilder() + .setSeconds(instant.getEpochSecond()) + .setNanos(instant.getNano()) + .build()).build(); + } else if (source instanceof ZonedDateTime) { + ZonedDateTime zonedDateTime = (ZonedDateTime) source; + Instant instant = zonedDateTime.toInstant(); + return builder.setTimestampValue(Timestamp.newBuilder() + .setSeconds(instant.getEpochSecond()) + .setNanos(instant.getNano()) + .build()).build(); + } else if (source instanceof java.time.Duration) { + java.time.Duration duration = (java.time.Duration) source; + return builder.setDurationValue(Duration.newBuilder() + .setSeconds(duration.getSeconds()) + .setNanos(duration.getNano()) + .build()).build(); + } else if (source instanceof byte[]) { + return builder.setBytesValue(ByteString.copyFrom((byte[]) source)).build(); + } else { + // For any other type, convert to string + return builder.setStringValue(source.toString()).build(); + } + } +} diff --git a/src/main/java/io/kurrent/dbclient/EventData.java b/src/main/java/io/kurrent/dbclient/EventData.java index ee94fe96..864ce854 100644 --- a/src/main/java/io/kurrent/dbclient/EventData.java +++ b/src/main/java/io/kurrent/dbclient/EventData.java @@ -98,3 +98,4 @@ public static EventDataBuilder builderAsBinary(UUID eventId, String eventType, b } } + diff --git a/src/main/java/io/kurrent/dbclient/EventDataBuilder.java b/src/main/java/io/kurrent/dbclient/EventDataBuilder.java index fde65402..76bd05ed 100644 --- a/src/main/java/io/kurrent/dbclient/EventDataBuilder.java +++ b/src/main/java/io/kurrent/dbclient/EventDataBuilder.java @@ -1,8 +1,5 @@ package io.kurrent.dbclient; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.json.JsonMapper; - import java.util.UUID; /** diff --git a/src/main/java/io/kurrent/dbclient/KurrentDBClient.java b/src/main/java/io/kurrent/dbclient/KurrentDBClient.java index 3cbea889..2dc0c679 100644 --- a/src/main/java/io/kurrent/dbclient/KurrentDBClient.java +++ b/src/main/java/io/kurrent/dbclient/KurrentDBClient.java @@ -75,7 +75,7 @@ public CompletableFuture appendToStream(String streamName, AppendTo return new AppendToStream(this.getGrpcClient(), streamName, events, options).execute(); } - public CompletableFuture multiAppend(AppendToStreamOptions options, Iterator requests) { + public CompletableFuture multiStreamAppend(Iterator requests) { return new MultiStreamAppend(this.getGrpcClient(), requests).execute(); } diff --git a/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java b/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java index 9c434a7b..21195be3 100644 --- a/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java +++ b/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java @@ -12,6 +12,7 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.concurrent.CompletableFuture; class MultiStreamAppend { @@ -42,22 +43,29 @@ private CompletableFuture append(WorkItemArgs args) { while (this.requests.hasNext()) { AppendStreamRequest request = this.requests.next(); io.kurrentdb.protocol.streams.v2.AppendStreamRequest.Builder builder = io.kurrentdb.protocol.streams.v2.AppendStreamRequest.newBuilder() + .setExpectedRevision(request.getExpectedState().toRawLong()) .setStream(request.getStreamName()); while (request.getEvents().hasNext()) { EventData event = request.getEvents().next(); - builder.addRecords(AppendRecord.newBuilder() + AppendRecord.Builder recordBuilder = AppendRecord.newBuilder() .setData(ByteString.copyFrom(event.getEventData())) - .setRecordId(event.getEventId().toString()) - .putProperties(SystemMetadataKeys.DATA_FORMAT, DynamicValue - .newBuilder() - .setStringValue(ContentTypeMapper.toSchemaDataFormat(event.getContentType())) - .build()) - .putProperties(SystemMetadataKeys.SCHEMA_NAME, DynamicValue - .newBuilder() - .setStringValue(event.getEventType()) - .build()) + .setRecordId(event.getEventId().toString()) + .putProperties(SystemMetadataKeys.DATA_FORMAT, DynamicValue + .newBuilder() + .setStringValue(ContentTypeMapper.toSchemaDataFormat(event.getContentType())) + .build()) + .putProperties(SystemMetadataKeys.SCHEMA_NAME, DynamicValue + .newBuilder() + .setStringValue(event.getEventType()) .build()); + + if (event.getUserMetadata() != null) { + Map userMetadataProperties = DynamicValueMapper.mapJsonToDynamicValueMap(event.getUserMetadata()); + recordBuilder.putAllProperties(userMetadataProperties); + } + + builder.addRecords(recordBuilder.build()); } requestStream.onNext(builder.build()); diff --git a/src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java b/src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java index 122ce7ca..8244d34b 100644 --- a/src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java +++ b/src/test/java/io/kurrent/dbclient/MultiStreamAppendTests.java @@ -4,11 +4,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; +import java.io.IOException; +import java.time.Instant; +import java.util.*; import java.util.concurrent.ExecutionException; +@SuppressWarnings("rawtypes") public class MultiStreamAppendTests implements ConnectionAware { static private Database database; static private Logger logger; @@ -35,7 +36,7 @@ public static void cleanup() { } @Test - public void testMultiStreamAppend() throws ExecutionException, InterruptedException { + public void testMultiStreamAppend() throws ExecutionException, InterruptedException, IOException { KurrentDBClient client = getDefaultClient(); Optional version = client.getServerVersion().get(); @@ -45,18 +46,64 @@ public void testMultiStreamAppend() throws ExecutionException, InterruptedExcept "Multi-stream append is not supported server versions below 25.0.0" ); - List requests = new ArrayList<>(); + // Arrange + String streamName1 = generateName(); + String streamName2 = generateName(); - List events = new ArrayList<>(); - for (int i = 0; i < 10; i++) - events.add(EventData.builderAsBinary("created", new byte[0]).build()); + Map metadata = new HashMap<>(); + metadata.put("stringProperty", "hello world"); + metadata.put("intProperty", 42); + metadata.put("longProperty", 9876543210L); + metadata.put("booleanProperty", true); + metadata.put("doubleProperty", 3.14159); + metadata.put("nullProperty", null); + metadata.put("timestampProperty", Instant.now().toString()); - requests.add(new AppendStreamRequest("foobar", events.iterator(), StreamState.any())); - requests.add(new AppendStreamRequest("baz", events.iterator(), StreamState.any())); + byte[] metadataBytes = mapper.writeValueAsBytes(metadata); + + EventData event1 = EventData.builderAsJson("event-a", "{\"data\":\"test1\"}".getBytes()) + .metadataAsBytes(metadataBytes) + .build(); - MultiAppendWriteResult result = client.multiAppend(AppendToStreamOptions.get(), requests.iterator()).get(); + EventData event2 = EventData.builderAsBinary("event-b", new byte[0]).build(); + List events1 = Collections.singletonList(event1); + List events2 = Collections.singletonList(event2); + + List requests = Arrays.asList( + new AppendStreamRequest(streamName1, events1.iterator(), StreamState.noStream()), + new AppendStreamRequest(streamName2, events2.iterator(), StreamState.noStream()) + ); + + // Act + MultiAppendWriteResult result = client.multiStreamAppend(requests.iterator()).get(); + + // Assert Assertions.assertTrue(result.getSuccesses().isPresent()); + Assertions.assertFalse(result.getSuccesses().get().isEmpty()); + + List readEvents1 = client.readStream(streamName1, ReadStreamOptions.get()).get().getEvents(); + Assertions.assertEquals(1, readEvents1.size()); + + ResolvedEvent readEvent1 = readEvents1.get(0); + Assertions.assertEquals(event1.getEventType(), readEvent1.getEvent().getEventType()); + + byte[] readMetadata = readEvent1.getEvent().getUserMetadata(); + Assertions.assertNotNull(readMetadata); + Assertions.assertTrue(readMetadata.length > 0); + + Map deserializedMetadata = mapper.readValue(readMetadata, Map.class); + Assertions.assertEquals(metadata.get("stringProperty"), deserializedMetadata.get("stringProperty")); + Assertions.assertEquals(metadata.get("intProperty"), deserializedMetadata.get("intProperty")); + Assertions.assertEquals(metadata.get("longProperty"), ((Number) deserializedMetadata.get("longProperty")).longValue()); + Assertions.assertEquals(metadata.get("booleanProperty"), deserializedMetadata.get("booleanProperty")); + Assertions.assertEquals((Double) metadata.get("doubleProperty"), ((Number) deserializedMetadata.get("doubleProperty")).doubleValue(), 0.00001); + Assertions.assertEquals(metadata.get("timestampProperty"), deserializedMetadata.get("timestampProperty")); + Assertions.assertNull(deserializedMetadata.get("nullProperty")); + + List readEvents2 = client.readStream(streamName2, ReadStreamOptions.get()).get().getEvents(); + Assertions.assertEquals(1, readEvents2.size()); + Assertions.assertEquals(event2.getEventType(), readEvents2.get(0).getEvent().getEventType()); } @Test @@ -80,9 +127,136 @@ public void testMultiStreamAppendWhenUnsupported() throws ExecutionException, In ExecutionException e = Assertions.assertThrows( ExecutionException.class, - () -> client.multiAppend(AppendToStreamOptions.get(), requests.iterator()).get()); + () -> client.multiStreamAppend(requests.iterator()).get()); Assertions.assertInstanceOf(UnsupportedOperationException.class, e.getCause()); } -} + @Test + public void testMultiStreamAppendStreamRevisionConflict() throws ExecutionException, InterruptedException { + KurrentDBClient client = getDefaultClient(); + + Optional version = client.getServerVersion().get(); + + Assumptions.assumeTrue( + version.isPresent() && version.get().isGreaterOrEqualThan(25, 0), + "Multi-stream append is not supported server versions below 25.0.0" + ); + + // Arrange + String streamName = generateName(); + + EventData event1 = EventData.builderAsJson("event-1", "{}".getBytes()).build(); + EventData event2 = EventData.builderAsJson("event-2", "{}".getBytes()).build(); + EventData event3 = EventData.builderAsJson("event-3", "{}".getBytes()).build(); + + client.appendToStream( + streamName, + AppendToStreamOptions.get().streamState(StreamState.noStream()), + event1, event2, event3 + ).get(); + + ResolvedEvent lastEvent = client.readStream(streamName, ReadStreamOptions.get().maxCount(1).fromEnd().backwards()).get().getEvents().get(0); + + List requests = Collections.singletonList( + new AppendStreamRequest( + streamName, + Collections.singletonList(EventData.builderAsBinary("event-4", "{}".getBytes()).build()).iterator(), + StreamState.noStream() + ) + ); + + // Act + MultiAppendWriteResult result = client.multiStreamAppend(requests.iterator()).get(); + + // Assert + Assertions.assertTrue(result.getFailures().isPresent()); + Assertions.assertFalse(result.getFailures().get().isEmpty()); + + AppendStreamFailure failure = result.getFailures().get().get(0); + Assertions.assertEquals(streamName, failure.getStreamName()); + + MultiAppendErrorVisitor visitor = new MultiAppendErrorVisitor(); + failure.visit(visitor); + + Assertions.assertTrue(visitor.wasWrongExpectedRevisionVisited()); + Assertions.assertEquals(lastEvent.getOriginalEvent().getRevision(), visitor.getActualRevision()); + } + + @Test + public void testMultiStreamAppendStreamDeleted() throws ExecutionException, InterruptedException { + KurrentDBClient client = getDefaultClient(); + + Optional version = client.getServerVersion().get(); + + Assumptions.assumeTrue( + version.isPresent() && version.get().isGreaterOrEqualThan(25, 0), + "Multi-stream append is not supported server versions below 25.0.0" + ); + + // Arrange + String streamName = generateName(); + + EventData event1 = EventData.builderAsJson("event-1", "{}".getBytes()).build(); + + client.appendToStream( + streamName, + AppendToStreamOptions.get().streamState(StreamState.noStream()), + event1 + ).get(); + + client.tombstoneStream(streamName).get(); + + List requests = Collections.singletonList( + new AppendStreamRequest( + streamName, + Collections.singletonList(EventData.builderAsBinary("event-2", "{}".getBytes()).build()).iterator(), + StreamState.noStream() + ) + ); + + // Act + MultiAppendWriteResult result = client.multiStreamAppend(requests.iterator()).get(); + + // Assert + Assertions.assertTrue(result.getFailures().isPresent()); + Assertions.assertFalse(result.getFailures().get().isEmpty()); + + AppendStreamFailure failure = result.getFailures().get().get(0); + Assertions.assertEquals(streamName, failure.getStreamName()); + + MultiAppendErrorVisitor visitor = new MultiAppendErrorVisitor(); + failure.visit(visitor); + + Assertions.assertTrue(visitor.wasStreamDeletedVisited()); + } + + private static class MultiAppendErrorVisitor implements MultiAppendStreamErrorVisitor { + private boolean wrongExpectedRevisionVisited = false; + private boolean streamDeletedVisited = false; + private long actualRevision = -1; + + @Override + public void onWrongExpectedRevision(long streamRevision) { + this.wrongExpectedRevisionVisited = true; + this.actualRevision = streamRevision; + } + + @Override + public void onStreamDeleted() { + this.streamDeletedVisited = true; + } + + public boolean wasWrongExpectedRevisionVisited() { + return wrongExpectedRevisionVisited; + } + + public boolean wasStreamDeletedVisited() { + return streamDeletedVisited; + } + + public long getActualRevision() { + return actualRevision; + } + } +} From 249b3991e31d390bdce79d3df007cefbf74c128d Mon Sep 17 00:00:00 2001 From: William Chong Date: Wed, 6 Aug 2025 12:03:04 +0400 Subject: [PATCH 15/18] [DEV-762] Change operation type of reading to regular (#339) * Change operation type of reading to regular * Allows overriding deadline at the call level --- .../io/kurrent/dbclient/ReadAllOptions.java | 1 - .../kurrent/dbclient/ReadStreamOptions.java | 1 - .../dbclient/streams/DeadlineTests.java | 61 +++++++++++++++++-- 3 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/kurrent/dbclient/ReadAllOptions.java b/src/main/java/io/kurrent/dbclient/ReadAllOptions.java index 49aee11e..4d06a94c 100644 --- a/src/main/java/io/kurrent/dbclient/ReadAllOptions.java +++ b/src/main/java/io/kurrent/dbclient/ReadAllOptions.java @@ -8,7 +8,6 @@ public class ReadAllOptions extends OptionsWithPositionAndResolveLinkTosBase opts.defaultDeadline(1) .maxDiscoverAttempts(3)); @@ -21,11 +21,11 @@ default void testDefaultDeadline() throws Throwable { ExecutionException e = Assertions.assertThrows(ExecutionException.class, () -> client.appendToStream("toto", data).get()); StatusRuntimeException status = (StatusRuntimeException) e.getCause(); - Assertions.assertEquals(status.getStatus().getCode(), Status.Code.DEADLINE_EXCEEDED); + Assertions.assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getStatus().getCode()); } @RetryingTest(3) - default void testOptionLevelDeadline() throws Throwable { + default void testOptionLevelDeadline() { KurrentDBClient client = getDatabase().defaultClient(); UUID id = UUID.randomUUID(); @@ -34,6 +34,59 @@ default void testOptionLevelDeadline() throws Throwable { ExecutionException e = Assertions.assertThrows(ExecutionException.class, () -> client.appendToStream("toto", options, data).get()); StatusRuntimeException status = (StatusRuntimeException) e.getCause(); - Assertions.assertEquals(status.getStatus().getCode(), Status.Code.DEADLINE_EXCEEDED); + Assertions.assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getStatus().getCode()); + } + + @RetryingTest(3) + default void testReadStreamWithDefaultDeadline() { + KurrentDBClient client = getDatabase().connectWith(opts -> + opts.defaultDeadline(1) + .maxDiscoverAttempts(3)); + + ReadStreamOptions options = ReadStreamOptions.get(); + + ExecutionException e = Assertions.assertThrows(ExecutionException.class, () -> client.readStream("$users", options).get()); + StatusRuntimeException status = (StatusRuntimeException) e.getCause(); + + Assertions.assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getStatus().getCode()); + } + + @RetryingTest(3) + default void testReadStreamWithLevelDeadline() { + KurrentDBClient client = getDefaultClient(); + + ExecutionException e = Assertions.assertThrows( + ExecutionException.class, + () -> client.readStream("$users", ReadStreamOptions.get().deadline(1)).get() + ); + StatusRuntimeException status = (StatusRuntimeException) e.getCause(); + + Assertions.assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getStatus().getCode()); + } + + @RetryingTest(3) + default void testReadAllWithDefaultDeadline() { + KurrentDBClient client = getDatabase().connectWith(opts -> + opts.defaultDeadline(1) + .maxDiscoverAttempts(3)); + + ReadAllOptions options = ReadAllOptions.get(); + + ExecutionException e = Assertions.assertThrows(ExecutionException.class, () -> client.readAll(options).get()); + StatusRuntimeException status = (StatusRuntimeException) e.getCause(); + + Assertions.assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getStatus().getCode()); + } + + @RetryingTest(3) + default void testReadAllWithLevelDeadline() { + KurrentDBClient client = getDefaultClient(); + + ReadAllOptions options = ReadAllOptions.get().deadline(1); + + ExecutionException e = Assertions.assertThrows(ExecutionException.class, () -> client.readAll(options).get()); + StatusRuntimeException status = (StatusRuntimeException) e.getCause(); + + Assertions.assertEquals(Status.Code.DEADLINE_EXCEEDED, status.getStatus().getCode()); } } From 633486ea0d2c81b5084583c1ec768b293ff0dd48 Mon Sep 17 00:00:00 2001 From: William Chong Date: Wed, 13 Aug 2025 15:15:26 +0400 Subject: [PATCH 16/18] docs: Multi stream append (#340) --- docs/api/appending-events.md | 146 ++++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 1 deletion(-) diff --git a/docs/api/appending-events.md b/docs/api/appending-events.md index f471a71d..6b00046a 100644 --- a/docs/api/appending-events.md +++ b/docs/api/appending-events.md @@ -245,4 +245,148 @@ AppendToStreamOptions options = AppendToStreamOptions.get() client.appendToStream("some-stream", options, eventData) .get(); -``` \ No newline at end of file +``` + +## Append to multiple streams + +::: note +This feature is only available in KurrentDB 25.1 and later. +::: + +You can append events to multiple streams in a single atomic operation. Either all streams are updated, or the entire operation fails. + +The `multiStreamAppend` method accepts a collection of `AppendStreamRequest` objects and returns a `MultiAppendWriteResult`. Each `AppendStreamRequest` contains: + +- **streamName** - The name of the stream +- **expectedState** - The expected state of the stream for optimistic concurrency control +- **events** - A collection of `EventData` objects to append + +The operation returns a `MultiAppendWriteResult` that contains either: +- A list of `AppendStreamSuccess` objects if all streams were successfully updated +- A list of `AppendStreamFailure` objects if any streams failed to update + +::: warning +Event metadata in `EventData` must be valid JSON objects. This requirement will +be removed in a future major release. +::: + +Here's a basic example of appending events to multiple streams: + +```java +JsonMapper mapper = new JsonMapper(); + +Map metadata = new HashMap<>(); +metadata.put("timestamp", Instant.now().toString()); + metadata.put("source", "OrderProcessingSystem"); +metadata.put("version", 1.0); + +byte[] metadataBytes = mapper.writeValueAsBytes(metadata); + +EventData orderEvent = EventData + .builderAsJson("OrderCreated", mapper.writeValueAsBytes(new OrderCreated("12345", 99.99))) + .metadataAsBytes(metadataBytes) + .build(); + +EventData inventoryEvent = EventData + .builderAsJson("ProductPurchased", mapper.writeValueAsBytes(new ProductPurchased("ABC123", 2, 19.99))) + .metadataAsBytes(metadataBytes) + .build(); + +List requests = Arrays.asList( + new AppendStreamRequest( + "order-stream-1", + Collections.singletonList(orderEvent).iterator(), + StreamState.any() + ), + new AppendStreamRequest( + "product-stream-1", + Collections.singletonList(inventoryEvent).iterator(), + StreamState.any() + ) +); + +MultiAppendWriteResult result = client.multiStreamAppend(requests.iterator()).get(); + +if (result.getSuccesses().isPresent()) + result.getSuccesses().get().forEach(success -> { + System.out.println(success.getStreamName() + " updated at " + success.getPosition()); + }); +``` + +If the operation doesn't succeed, you can handle the failures as follows: + +```java +if (result.getFailures().isPresent()) { + MultiAppendErrorVisitor visitor = new MultiAppendErrorVisitor(); + result.getFailures().get().forEach(failure -> { + failure.visit(visitor); + + if (visitor.wasWrongExpectedRevisionVisited()) { + System.out.println("Wrong revision for stream: " + failure.getStreamName()); + } else if (visitor.wasStreamDeletedVisited()) { + System.out.println("Stream deleted: " + failure.getStreamName()); + } else if (visitor.wasAccessDenied()) { + System.out.println("Access denied: " + failure.getStreamName()); + } else if (visitor.wasTransactionMaxSizeExceeded()) { + System.out.println("Transaction too large: " + failure.getStreamName()); + } else { + System.out.println("Unknown error: " + failure.getStreamName()); + } + }); +} +``` + +::: details Click here to see the implementaton of `MultiAppendErrorVisitor` + +```java +class MultiAppendErrorVisitor implements MultiAppendStreamErrorVisitor { + private boolean wrongExpectedRevisionVisited = false; + private boolean streamDeletedVisited = false; + private boolean transactionMaxSizeExceeded = false; + private boolean accessDenied = false; + private long actualRevision = -1; + + @Override + public void onAccessDenied(ErrorDetails.AccessDenied detail) { + this.accessDenied = true; + } + + @Override + public void onWrongExpectedRevision(long streamRevision) { + this.wrongExpectedRevisionVisited = true; + this.actualRevision = streamRevision; + } + + @Override + public void onStreamDeleted() { + this.streamDeletedVisited = true; + } + + @Override + public void onTransactionMaxSizeExceeded(int maxSize) { + this.transactionMaxSizeExceeded = true; + } + + public boolean wasWrongExpectedRevisionVisited() { + return wrongExpectedRevisionVisited; + } + + public boolean wasStreamDeletedVisited() { + return streamDeletedVisited; + } + + public boolean wasAccessDenied() { + return accessDenied; + } + + public boolean wasTransactionMaxSizeExceeded() { + return transactionMaxSizeExceeded; + } + + public long getActualRevision() { + return actualRevision; + } +} +``` + +::: From 891abe81405d1494ebb8ec4d2db375e2f9bec267 Mon Sep 17 00:00:00 2001 From: William Chong Date: Wed, 20 Aug 2025 16:25:40 +0400 Subject: [PATCH 17/18] feat: add support for PinnedByCorrelation consumer strategy in persistent subscriptions (#341) --- .../AbstractCreatePersistentSubscription.java | 12 +++- .../dbclient/NamedConsumerStrategy.java | 13 ++++ ...PersistentSubscriptionManagementTests.java | 65 +++++++++++++++++-- 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/kurrent/dbclient/AbstractCreatePersistentSubscription.java b/src/main/java/io/kurrent/dbclient/AbstractCreatePersistentSubscription.java index a7d24ade..4e9b1dd0 100644 --- a/src/main/java/io/kurrent/dbclient/AbstractCreatePersistentSubscription.java +++ b/src/main/java/io/kurrent/dbclient/AbstractCreatePersistentSubscription.java @@ -5,6 +5,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Optional; import java.util.concurrent.CompletableFuture; abstract class AbstractCreatePersistentSubscription { @@ -31,6 +32,8 @@ protected Persistent.CreateReq.Settings.Builder createSettings(){ @SuppressWarnings({"unchecked", "deprecation"}) public CompletableFuture execute() { return this.client.runWithArgs(args -> { + Optional serverVersion = args.getServerVersion(); + CompletableFuture result = new CompletableFuture(); PersistentSubscriptionsGrpc.PersistentSubscriptionsStub client = GrpcUtils.configureStub(PersistentSubscriptionsGrpc.newStub(args.getChannel()), this.client.getSettings(), this.options); @@ -56,8 +59,15 @@ public CompletableFuture execute() { settingsBuilder.setNamedConsumerStrategy(Persistent.CreateReq.ConsumerStrategy.RoundRobin); } else if (settings.getNamedConsumerStrategy().isPinned()) { settingsBuilder.setNamedConsumerStrategy(Persistent.CreateReq.ConsumerStrategy.Pinned); + } else if (settings.getNamedConsumerStrategy().isPinnedByCorrelation()) { + if (serverVersion.get().isGreaterThan(21, 10, 0)) { + settingsBuilder.setConsumerStrategy(settings.getNamedConsumerStrategy().toString()); + } else { + logger.error("Consumer strategy: '{}' is only available on server 21.10.1 and above", NamedConsumerStrategy.PINNED_BY_CORRELATION); + throw new UnsupportedFeatureException(); + } } else { - logger.error(String.format("Unsupported named consumer strategy: '%s'", settings.getNamedConsumerStrategy().toString())); + logger.error("Unsupported named consumer strategy: '{}'", settings.getNamedConsumerStrategy().toString()); throw new UnsupportedFeatureException(); } diff --git a/src/main/java/io/kurrent/dbclient/NamedConsumerStrategy.java b/src/main/java/io/kurrent/dbclient/NamedConsumerStrategy.java index 78275d92..38f8aaa7 100644 --- a/src/main/java/io/kurrent/dbclient/NamedConsumerStrategy.java +++ b/src/main/java/io/kurrent/dbclient/NamedConsumerStrategy.java @@ -28,6 +28,11 @@ public class NamedConsumerStrategy { */ public static final NamedConsumerStrategy PINNED = new NamedConsumerStrategy("Pinned"); + /** + * This is similar to the Pinned strategy, but instead of using the source stream id to bucket the messages, it distributes the events based on the event's correlationId. + */ + public static final NamedConsumerStrategy PINNED_BY_CORRELATION = new NamedConsumerStrategy("PinnedByCorrelation"); + NamedConsumerStrategy(String value) { this.value = value; } @@ -53,6 +58,14 @@ public boolean isPinned() { return isNamed("Pinned"); } + + /** + * Checks if it's a PinnedByCorrelation strategy. + */ + public boolean isPinnedByCorrelation() { + return isNamed("PinnedByCorrelation"); + } + /** * Checks if the strategy's name matches the string passed as a parameter. */ diff --git a/src/test/java/io/kurrent/dbclient/persistentsubscriptions/PersistentSubscriptionManagementTests.java b/src/test/java/io/kurrent/dbclient/persistentsubscriptions/PersistentSubscriptionManagementTests.java index 0fe9ce63..c87a2d23 100644 --- a/src/test/java/io/kurrent/dbclient/persistentsubscriptions/PersistentSubscriptionManagementTests.java +++ b/src/test/java/io/kurrent/dbclient/persistentsubscriptions/PersistentSubscriptionManagementTests.java @@ -3,11 +3,15 @@ import io.kurrent.dbclient.*; import com.fasterxml.jackson.databind.json.JsonMapper; import org.junit.jupiter.api.*; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.*; import java.util.List; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; @TestMethodOrder(MethodOrderer.OrderAnnotation.class) @SuppressWarnings("unchecked") @@ -29,7 +33,7 @@ default void testListPersistentSubscriptions() throws Throwable { List subs = client.listAll().get(); int count = 0; - for (PersistentSubscriptionInfo info: subs) { + for (PersistentSubscriptionInfo info : subs) { if (info.getEventSource().equals(streamA) || info.getEventSource().equals(streamB)) { count++; } @@ -122,7 +126,7 @@ default void testGetPersistentSubscriptionInfoToAll() throws Throwable { @Test @Order(6) - default void testGetPersistentSubscriptionInfoNotExisting() throws Throwable { + default void testGetPersistentSubscriptionInfoNotExisting() throws Throwable { KurrentDBPersistentSubscriptionsClient client = getDefaultPersistentSubscriptionClient(); Optional result = client.getInfoToStream(generateName(), generateName()).get(); @@ -147,6 +151,7 @@ default void testReplayParkedMessages() throws Throwable { client.subscribeToStream(streamName, groupName, new PersistentSubscriptionListener() { int count = 0; + @Override public void onEvent(PersistentSubscription subscription, int retryCount, ResolvedEvent event) { if (count < 2) @@ -206,6 +211,7 @@ default void testReplayParkedMessagesToAll() throws Throwable { client.subscribeToAll(groupName, new PersistentSubscriptionListener() { int count = 0; + @Override public void onEvent(PersistentSubscription subscription, int retryCount, ResolvedEvent event) { if (count < 2 && event.getOriginalEvent().getStreamId().equals(streamName)) @@ -268,9 +274,9 @@ default void testEncoding() throws Throwable { break; } - Assertions.assertTrue(info.isPresent()); - Assertions.assertEquals(info.get().getEventSource(), streamName); - Assertions.assertEquals(info.get().getGroupName(), groupName); + Assertions.assertTrue(info.isPresent()); + Assertions.assertEquals(info.get().getEventSource(), streamName); + Assertions.assertEquals(info.get().getGroupName(), groupName); } @Test @@ -279,4 +285,53 @@ default void testRestartSubsystem() throws Throwable { KurrentDBPersistentSubscriptionsClient client = getDefaultPersistentSubscriptionClient(); client.restartSubsystem().get(); } + + @ParameterizedTest + @ArgumentsSource(NamedConsumerStrategyProvider.class) + default void testCreatePersistentSubscriptionToAllWithConsumerStrategies(NamedConsumerStrategy strategy) throws Throwable { + KurrentDBPersistentSubscriptionsClient client = getDefaultPersistentSubscriptionClient(); + String groupName = String.format("/foo/%s/group", generateName()); + + CreatePersistentSubscriptionToAllOptions options = CreatePersistentSubscriptionToAllOptions.get() + .namedConsumerStrategy(strategy); + + client.createToAll(groupName, options).get(); + + Optional result = client.getInfoToAll(groupName).get(); + Assertions.assertTrue(result.isPresent(), "Subscription should be created"); + + Assertions.assertEquals(groupName, result.get().getGroupName()); + Assertions.assertEquals(strategy.toString(), result.get().getSettings().getNamedConsumerStrategy().toString()); + } + + @ParameterizedTest + @ArgumentsSource(NamedConsumerStrategyProvider.class) + default void testCreatePersistentSubscriptionToStreamWithConsumerStrategies(NamedConsumerStrategy strategy) throws Throwable { + KurrentDBPersistentSubscriptionsClient client = getDefaultPersistentSubscriptionClient(); + String streamName = String.format("/foo/%s/stream", generateName()); + String groupName = String.format("/foo/%s/group", generateName()); + + CreatePersistentSubscriptionToStreamOptions options = CreatePersistentSubscriptionToStreamOptions.get() + .namedConsumerStrategy(strategy); + + client.createToStream(streamName, groupName, options).get(); + + Optional result = client.getInfoToStream(streamName, groupName).get(); + Assertions.assertTrue(result.isPresent(), "Subscription should be created"); + + Assertions.assertEquals(groupName, result.get().getGroupName()); + Assertions.assertEquals(strategy.toString(), result.get().getSettings().getNamedConsumerStrategy().toString()); + } } + +class NamedConsumerStrategyProvider implements ArgumentsProvider { + @Override + public Stream provideArguments(ExtensionContext context) { + return Stream.of( + Arguments.of(NamedConsumerStrategy.DISPATCH_TO_SINGLE), + Arguments.of(NamedConsumerStrategy.ROUND_ROBIN), + Arguments.of(NamedConsumerStrategy.PINNED), + Arguments.of(NamedConsumerStrategy.PINNED_BY_CORRELATION) + ); + } +} \ No newline at end of file From 80a3bd04a556a1a575331748e36ad37f3c8bc8fc Mon Sep 17 00:00:00 2001 From: William Chong Date: Mon, 25 Aug 2025 16:00:59 +0400 Subject: [PATCH 18/18] Add tracing for multi stream append (#338) --- build.gradle | 4 +- .../kurrent/dbclient/AppendStreamFailure.java | 10 +- .../io/kurrent/dbclient/ClientTelemetry.java | 96 +++++++++++++- .../dbclient/ClientTelemetryConstants.java | 1 + .../kurrent/dbclient/MultiStreamAppend.java | 12 +- .../io/kurrent/dbclient/TelemetryTests.java | 15 +++ .../databases/DockerContainerDatabase.java | 2 +- .../StreamsTracingInstrumentationTests.java | 124 +++++++++++++++++- 8 files changed, 247 insertions(+), 17 deletions(-) diff --git a/build.gradle b/build.gradle index 5b51f211..a84cd8b5 100644 --- a/build.gradle +++ b/build.gradle @@ -84,8 +84,8 @@ dependencies { testImplementation 'org.slf4j:slf4j-simple:2.0.17' testImplementation "io.opentelemetry:opentelemetry-sdk" testImplementation "io.opentelemetry:opentelemetry-sdk-testing" - testImplementation 'io.opentelemetry:opentelemetry-exporter-logging:1.38.0' - testImplementation 'io.opentelemetry:opentelemetry-exporter-otlp-trace:1.14.0' + testImplementation "io.opentelemetry:opentelemetry-exporter-logging" + testImplementation "io.opentelemetry:opentelemetry-exporter-otlp" } tasks.withType(Test).configureEach { diff --git a/src/main/java/io/kurrent/dbclient/AppendStreamFailure.java b/src/main/java/io/kurrent/dbclient/AppendStreamFailure.java index 28218bef..887ec5b4 100644 --- a/src/main/java/io/kurrent/dbclient/AppendStreamFailure.java +++ b/src/main/java/io/kurrent/dbclient/AppendStreamFailure.java @@ -1,5 +1,7 @@ package io.kurrent.dbclient; +import io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase; + public class AppendStreamFailure { private final io.kurrentdb.protocol.streams.v2.AppendStreamFailure inner; @@ -12,21 +14,21 @@ public String getStreamName() { } public void visit(MultiAppendStreamErrorVisitor visitor) { - if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.STREAM_REVISION_CONFLICT) { + if (this.inner.getErrorCase() == ErrorCase.STREAM_REVISION_CONFLICT) { visitor.onWrongExpectedRevision(this.inner.getStreamRevisionConflict().getStreamRevision()); return; } - if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.ACCESS_DENIED) { + if (this.inner.getErrorCase() == ErrorCase.ACCESS_DENIED) { visitor.onAccessDenied(this.inner.getAccessDenied()); } - if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.STREAM_DELETED) { + if (this.inner.getErrorCase() == ErrorCase.STREAM_DELETED) { visitor.onStreamDeleted(); return; } - if (this.inner.getErrorCase() == io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase.TRANSACTION_MAX_SIZE_EXCEEDED) { + if (this.inner.getErrorCase() == ErrorCase.TRANSACTION_MAX_SIZE_EXCEEDED) { visitor.onTransactionMaxSizeExceeded(this.inner.getTransactionMaxSizeExceeded().getMaxSize()); return; } diff --git a/src/main/java/io/kurrent/dbclient/ClientTelemetry.java b/src/main/java/io/kurrent/dbclient/ClientTelemetry.java index e435bc93..0fe2f866 100644 --- a/src/main/java/io/kurrent/dbclient/ClientTelemetry.java +++ b/src/main/java/io/kurrent/dbclient/ClientTelemetry.java @@ -5,18 +5,19 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import io.grpc.ManagedChannel; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.trace.*; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.function.BiFunction; +import static io.kurrentdb.protocol.streams.v2.AppendStreamFailure.*; + class ClientTelemetry { private static final ClientTelemetryTags DEFAULT_ATTRIBUTES = new ClientTelemetryTags() {{ put(ClientTelemetryAttributes.Database.SYSTEM, ClientTelemetryConstants.INSTRUMENTATION_NAME); @@ -122,6 +123,93 @@ static CompletableFuture traceAppend( } } + static CompletableFuture traceMultiStreamAppend( + BiFunction, CompletableFuture> multiAppendOperation, + WorkItemArgs args, + Iterator requests, KurrentDBClientSettings settings) { + + List requestsWithTracing = new ArrayList<>(); + + Span span = createSpan( + ClientTelemetryConstants.Operations.MULTI_APPEND, + SpanKind.CLIENT, + null, + ClientTelemetryTags.builder() + .withServerTagsFromGrpcChannel(args.getChannel()) + .withServerTagsFromClientSettings(settings) + .withOptionalDatabaseUserTag(settings.getDefaultCredentials()) + .build()); + + while (requests.hasNext()) { + AppendStreamRequest request = requests.next(); + + List eventsWithTracing = new ArrayList<>(); + while (request.getEvents().hasNext()) + eventsWithTracing.add(request.getEvents().next()); + + List tracedEvents = tryInjectTracingContext(span, eventsWithTracing); + + requestsWithTracing.add(new AppendStreamRequest( + request.getStreamName(), + tracedEvents.iterator(), + request.getExpectedState() + )); + } + + return multiAppendOperation.apply(args, requestsWithTracing.iterator()) + .handle((result, throwable) -> { + if (throwable != null) { + span.setStatus(StatusCode.ERROR); + span.recordException(throwable); + span.end(); + throw new CompletionException(throwable); + } else { + if (result.getFailures().isPresent()) { + for (AppendStreamFailure failure : result.getFailures().get()) { + failure.visit(new MultiAppendStreamErrorVisitor() { + @Override + public void onWrongExpectedRevision(long streamRevision) { + span.addEvent("exception", Attributes.of( + AttributeKey.stringKey("exception.type"), ErrorCase.STREAM_REVISION_CONFLICT.toString(), + AttributeKey.longKey("exception.revision"), streamRevision + )); + } + + @Override + public void onAccessDenied(io.kurrentdb.protocol.streams.v2.ErrorDetails.AccessDenied detail) { + span.addEvent("exception", Attributes.of( + AttributeKey.stringKey("exception.type"), ErrorCase.ACCESS_DENIED.toString() + )); + } + + @Override + public void onStreamDeleted() { + span.addEvent("exception", Attributes.of( + AttributeKey.stringKey("exception.type"), ErrorCase.STREAM_DELETED.toString() + )); + } + + @Override + public void onTransactionMaxSizeExceeded(int maxSize) { + span.addEvent("exception", Attributes.of( + AttributeKey.stringKey("exception.type"), ErrorCase.TRANSACTION_MAX_SIZE_EXCEEDED.toString(), + AttributeKey.longKey("exception.maxSize"), (long) maxSize + )); + } + }); + } + span.setStatus(StatusCode.ERROR); + span.end(); + } else if (result.getSuccesses().isPresent()) { + span.setStatus(StatusCode.OK); + span.end(); + } + + return result; + } + }); + } + static void traceSubscribe(Runnable tracedOperation, String subscriptionId, ManagedChannel channel, KurrentDBClientSettings settings, UserCredentials optionalCallCredentials, RecordedEvent event) { diff --git a/src/main/java/io/kurrent/dbclient/ClientTelemetryConstants.java b/src/main/java/io/kurrent/dbclient/ClientTelemetryConstants.java index 5b5f359c..f4d77dc5 100644 --- a/src/main/java/io/kurrent/dbclient/ClientTelemetryConstants.java +++ b/src/main/java/io/kurrent/dbclient/ClientTelemetryConstants.java @@ -10,6 +10,7 @@ public static class Metadata { public static class Operations { public static final String APPEND = "streams.append"; + public static final String MULTI_APPEND = "streams.multi-append"; public static final String SUBSCRIBE = "streams.subscribe"; } } diff --git a/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java b/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java index 21195be3..0210d9b3 100644 --- a/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java +++ b/src/main/java/io/kurrent/dbclient/MultiStreamAppend.java @@ -25,10 +25,14 @@ public MultiStreamAppend(GrpcClient client, Iterator reques } public CompletableFuture execute() { - return this.client.runWithArgs(this::append); + return this.client.runWithArgs(args -> ClientTelemetry.traceMultiStreamAppend( + this::append, + args, + this.requests, + this.client.getSettings())); } - private CompletableFuture append(WorkItemArgs args) { + private CompletableFuture append(WorkItemArgs args, Iterator requests) { CompletableFuture result = new CompletableFuture<>(); if (!args.supportFeature(FeatureFlags.MULTI_STREAM_APPEND)) { @@ -40,8 +44,8 @@ private CompletableFuture append(WorkItemArgs args) { StreamObserver requestStream = client.multiStreamAppendSession(GrpcUtils.convertSingleResponse(result, this::onResponse)); try { - while (this.requests.hasNext()) { - AppendStreamRequest request = this.requests.next(); + while (requests.hasNext()) { + AppendStreamRequest request = requests.next(); io.kurrentdb.protocol.streams.v2.AppendStreamRequest.Builder builder = io.kurrentdb.protocol.streams.v2.AppendStreamRequest.newBuilder() .setExpectedRevision(request.getExpectedState().toRawLong()) .setStream(request.getStreamName()); diff --git a/src/test/java/io/kurrent/dbclient/TelemetryTests.java b/src/test/java/io/kurrent/dbclient/TelemetryTests.java index 2ee48799..5bfc0151 100644 --- a/src/test/java/io/kurrent/dbclient/TelemetryTests.java +++ b/src/test/java/io/kurrent/dbclient/TelemetryTests.java @@ -6,9 +6,12 @@ import io.kurrent.dbclient.telemetry.TracingContextInjectionTests; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.resources.Resource; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SdkTracerProvider; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -21,6 +24,8 @@ import java.util.function.Consumer; import java.util.stream.Collectors; +import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME; + public class TelemetryTests implements StreamsTracingInstrumentationTests, PersistentSubscriptionsTracingInstrumentationTests, TracingContextInjectionTests { static private Database database; static private Logger logger; @@ -39,10 +44,20 @@ public void beforeEach() { GlobalOpenTelemetry.resetForTest(); spanEndedHooks.add(recordedSpans::add); + OtlpGrpcSpanExporter otlpExporter = OtlpGrpcSpanExporter.builder() + .setEndpoint("http://localhost:4317") + .build(); + + Resource resource = Resource.getDefault().toBuilder() + .put(SERVICE_NAME, "kurrentdb") + .build(); + OpenTelemetrySdk.builder() .setTracerProvider(SdkTracerProvider .builder() .addSpanProcessor(new SpanProcessorSpy(spanEndedHooks)) + .addSpanProcessor(SimpleSpanProcessor.create(otlpExporter)) + .setResource(resource) .build()) .buildAndRegisterGlobal(); } diff --git a/src/test/java/io/kurrent/dbclient/databases/DockerContainerDatabase.java b/src/test/java/io/kurrent/dbclient/databases/DockerContainerDatabase.java index 8435e70e..656634fb 100644 --- a/src/test/java/io/kurrent/dbclient/databases/DockerContainerDatabase.java +++ b/src/test/java/io/kurrent/dbclient/databases/DockerContainerDatabase.java @@ -12,7 +12,7 @@ import java.util.Map; public class DockerContainerDatabase extends GenericContainer implements Database { - public static final String DEFAULT_IMAGE = "docker.kurrent.io/eventstore/eventstoredb-ee:lts"; + public static final String DEFAULT_IMAGE = "docker.cloudsmith.io/eventstore/kurrent-staging/kurrentdb:ci"; public static class Builder { String image; diff --git a/src/test/java/io/kurrent/dbclient/telemetry/StreamsTracingInstrumentationTests.java b/src/test/java/io/kurrent/dbclient/telemetry/StreamsTracingInstrumentationTests.java index 892814b7..542b4e1d 100644 --- a/src/test/java/io/kurrent/dbclient/telemetry/StreamsTracingInstrumentationTests.java +++ b/src/test/java/io/kurrent/dbclient/telemetry/StreamsTracingInstrumentationTests.java @@ -3,14 +3,18 @@ import io.kurrent.dbclient.*; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import io.kurrentdb.protocol.streams.v2.AppendStreamFailure.ErrorCase; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.sdk.trace.ReadableSpan; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Assumptions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; @@ -289,4 +293,120 @@ public void onEvent(Subscription subscription, ResolvedEvent event) { List subscribeSpans = getSpansForOperation(ClientTelemetryConstants.Operations.SUBSCRIBE); Assertions.assertTrue(subscribeSpans.isEmpty(), "No spans should be recorded for deleted events"); } + + @Test + default void testMultiStreamAppendIsInstrumentedWithTracingAsExpected() throws Throwable { + KurrentDBClient client = getDefaultClient(); + + Optional version = client.getServerVersion().get(); + + Assumptions.assumeTrue( + version.isPresent() && version.get().isGreaterOrEqualThan(25, 0), + "Multi-stream append is not supported server versions below 25.0.0" + ); + + String streamName1 = generateName(); + String streamName2 = generateName(); + + EventData event1 = EventData.builderAsJson("TestEvent", mapper.writeValueAsBytes(new Foo())) + .eventId(UUID.randomUUID()) + .build(); + + EventData event2 = EventData.builderAsJson("TestEvent", mapper.writeValueAsBytes(new Foo())) + .eventId(UUID.randomUUID()) + .build(); + + AppendStreamRequest request1 = new AppendStreamRequest( + streamName1, + Collections.singletonList(event1).iterator(), + StreamState.noStream() + ); + + AppendStreamRequest request2 = new AppendStreamRequest( + streamName2, + Collections.singletonList(event2).iterator(), + StreamState.noStream() + ); + + MultiAppendWriteResult result = client.multiStreamAppend( + Arrays.asList(request1, request2).iterator() + ).get(); + + Assertions.assertNotNull(result); + Assertions.assertTrue(result.getSuccesses().isPresent()); + + List spans = getSpansForOperation(ClientTelemetryConstants.Operations.MULTI_APPEND); + Assertions.assertEquals(1, spans.size()); + + assertSpanAttributeEquals(spans.get(0), ClientTelemetryAttributes.Database.SYSTEM, ClientTelemetryConstants.INSTRUMENTATION_NAME); + assertSpanAttributeEquals(spans.get(0), ClientTelemetryAttributes.Database.OPERATION, ClientTelemetryConstants.Operations.MULTI_APPEND); + assertSpanAttributeEquals(spans.get(0), ClientTelemetryAttributes.Database.USER, "admin"); + Assertions.assertEquals(StatusCode.OK, spans.get(0).toSpanData().getStatus().getStatusCode()); + Assertions.assertEquals(SpanKind.CLIENT, spans.get(0).getKind()); + } + + @Test + default void testMultiStreamAppendIsInstrumentedWithFailures() throws Throwable { + KurrentDBClient client = getDefaultClient(); + + Optional version = client.getServerVersion().get(); + + Assumptions.assumeTrue( + version.isPresent() && version.get().isGreaterOrEqualThan(25, 0), + "Multi-stream append is not supported server versions below 25.0.0" + ); + + String streamName1 = generateName(); + String streamName2 = generateName(); + + EventData event1 = EventData.builderAsJson("TestEvent", mapper.writeValueAsBytes(new Foo())) + .eventId(UUID.randomUUID()) + .build(); + + EventData event2 = EventData.builderAsJson("TestEvent", mapper.writeValueAsBytes(new Foo())) + .eventId(UUID.randomUUID()) + .build(); + + AppendStreamRequest request1 = new AppendStreamRequest( + streamName1, + Collections.singletonList(event1).iterator(), + StreamState.noStream() + ); + + AppendStreamRequest request2 = new AppendStreamRequest( + streamName2, + Collections.singletonList(event2).iterator(), + StreamState.streamExists() + ); + + MultiAppendWriteResult result = client.multiStreamAppend( + Arrays.asList(request1, request2).iterator() + ).get(); + + Assertions.assertNotNull(result); + Assertions.assertFalse(result.getSuccesses().isPresent()); + Assertions.assertTrue(result.getFailures().isPresent()); + + List spans = getSpansForOperation(ClientTelemetryConstants.Operations.MULTI_APPEND); + Assertions.assertEquals(1, spans.size()); + + ReadableSpan span = spans.get(0); + + Assertions.assertEquals(StatusCode.ERROR, span.toSpanData().getStatus().getStatusCode()); + Assertions.assertEquals("", span.toSpanData().getStatus().getDescription()); + + List events = span.toSpanData().getEvents(); + + Assertions.assertEquals(1, events.size()); + + io.opentelemetry.sdk.trace.data.EventData failureEvent = events.get(0); + + Assertions.assertEquals("exception", failureEvent.getName()); + + Assertions.assertEquals(ErrorCase.STREAM_REVISION_CONFLICT.toString(), + failureEvent.getAttributes().get(AttributeKey.stringKey("exception.type"))); + + Assertions.assertNotNull(failureEvent.getAttributes().get(AttributeKey.longKey("exception.revision"))); + Assertions.assertEquals(-1L, failureEvent.getAttributes().get(AttributeKey.longKey("exception.revision"))); + } }

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 M07*qoM6N<$g3?w6$N&HU literal 0 HcmV?d00001 diff --git a/docs/.vuepress/public/fonts/Solina-Bold.woff b/docs/.vuepress/public/fonts/Solina-Bold.woff new file mode 100644 index 0000000000000000000000000000000000000000..83746eecdd1638509bba87e165949f071e740be2 GIT binary patch literal 17888 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 literal 0 HcmV?d00001 diff --git a/docs/.vuepress/public/fonts/Solina-Bold.woff2 b/docs/.vuepress/public/fonts/Solina-Bold.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..813770ef1b25aacbadc5215c9fe8d322a146ddea GIT binary patch literal 16364 zcmV6 zmKS~$ieGvyeb?^z{=_rK@Y?Ef2mQ~Ok%ul*#3HPA^j;lQ`#Xb9AwF` zpe3fXAVSs&xDaxFJ$gNI0sQ};F0<8mWIDhuz^YQFXx0u;bwrh`09LD+*_CI%X7yy& z$>vH1(vc3Og|ij{j9pS45LBTmRo)d%sHHMpnKEt3Wd^4zm3rOXXy-nTBJIk3*Y3M^ zuk1djMFVtz4WI#NrP)#TtlqfYi+7XV2gnER2O?(n!Osdp~{%#HcK z84ZVsJp~3BrP5}!pk>vxppt|QpF#Q;!!bI>#cV)8g@XtM zdL%*&2^7#FA5K)G3A3>P%dj3hP>bU@jSFbPT|7Z6KI0FL;S5|rf+7vZtT-~6*;LU; zhDEGkJ>6W$6>~PZaCw&ov^&W`j`)Cm9zQsWINC(F zw~6++h-g_hmR?0ZP6p0GMV#5a618U(~&@Q{K2d_cRBzJHEBkT!GLp zOOK{umNPkdbIQ(}aJVbC8rq30_gNkdot`Wwa{u5f+d_%V#jJuYifF8Eat$cbNC;gB-6cipy@+Pkq7{~b zFa{&1Uo4>Nzd4nPvncOB1=*2LIiJFzB9GT@* zxoXs`*;=C2+MzuHX&AirLn%CLu;q~mv-gIxax4>KCt?)K_yS)A0 zVefSChx?OLcks%3kJ2HzxUhy!{vjT#;UpR4eVmadMz+B3)G=e(X$-Z6u<9<|X)JF} zB3Dd|E?sc`^f@$hTidZt8eYFV0X#DBtfB{R+thV2+Dt-Y>#l67C_PYMMc@20Mw;HO z>laGORzz*M|IlKGlSDls2abdAsJ>cpZ^+RikFl>EBFTWdTF0oDzTX) z5{EAyV~65+iT_xecJB>)FL!p`#9vPO=75Om*46nUvgIX@afZX(>xmjfBxs*OS|{P+ zN+;M=U~tYf-YCB9Ss+i(^|K3f?n!&%DGZB1c97K17!os*v>p^B^BDr$c_3F6_;UE` z?Tx5TT`j4Pv_AIHF~kHhwVPtvt#RGyrLwo)8Xjvav_iVZ46IJ7P~~bW?3RY}#>HG8 zzum=9eFnRvsZ8&*2Qf;_U}f+oHIb&~VidgBE-&@r!r(XuUZe;DTXSk$`mUz>cJ8uj z#j7M@1-cE?{od7dD}V>RFf}nzP78T`aq{QWS3sZHbuO3He1BwY&6K2lv%}v8_Ak8J z(k=ksL0VR5Y}VdEgBjXLSqkqgQeK+C zuB4oln;4h#NK<_`cTu4%rq?nt(Ej=uwDZC=OLe6YBngBk_FLTfn!jTZCg|{$xK8Xb2*vu zOf-eLurLWl$-Docg<5C>P|G{i7-ndx!C-)&eVLQOj;TlYvw@ypZBfncp&6H_Yi-wNRTKVzwtu8Q6!QEZt4V_OE;xq)cWRiqTf?oTNVKQ99CRkO1 zJ@mKaQuFGp=-H$D4pN> zS6L8CM$cb6tH9~qZ#hpOaWws-`5lg!DiNb2)(ItUjAr)tO-!)9V30NCX?xj%&_1-a*0!J3qfk@HX8hj z0l!UGewI*U<_*8q*VS@o^ooG*Rw(px{SYIQSeYD5S21>`+Q{y_n&6jQV;Cp)!@D;C zFODdGn;%eXGo_T@t{8xvubBh?@4bOyC(DA=3^y{Pl!$>rhn0_w+>;IKDgUjjWo)D| zU~~)Ke9Ljce7CG=Dc}U-7HFk0c(nMn)?g|;Fz}KYaKG~aIb6&fVeJa|Ltvnk3Rt&x zHN*;KHdYv>3MO&|Uxfy#VlHqEPOG`Q`X@f<%529xdgl0MK-~j_#bE7r;R229riJbE z#e|%Q6_}WS!fXoFFlO39G;$q3%s6u0#LM7%2Uk;UTDTC*QrE5~O}tEGU60lTd|X-ySRz-$1azWgDuBi>rLCEB~K1aarWDvhV-Y&j^T{O+Bqn;H+|NID& z?^5oz+YvSeog1y?_on?6ytFngTnFq0*lrjro7nG@$qEJ50Hg_M5rZhG7==ZQ;Sxqu zh3EigF~>G^_66dveuz!(&E6P`o5B+0T$vE~@yN&Hvw=x%PmyG>HaZBE^_SNZ9MrPF zwY`ZH8iNzo!1@S-*fcd9sHSpo=bG+bw#1CaDtWsXK-}T z3UI;$mj^DPYQ_y(H4p>1i`FjG15ePfXk(D4b_OUxuNPPcylv)d+rJUoKHz7&7X0to zMYRh7j|Ucv!A0m8xC9*sy`d9y89MnA2ChJ-z|}$Z!Hr-s!oQP2lbr{VFFT+MK@_+J zT>`g5=Wusi38F(62Q0YBx|e`^gRX*R=r%hhbOXde_Xd_S;zPF=9)d*1qeb_FW#AcO zIYFxC`(qJeP=8z11t7;1DB z=#yba!~)yxv>_SvnSAtuz65KbZx~|L4S~Mj2xLXj4@y*djRL!EQ)81sHs0*e?|aQK zeUt=MpbX5$G?k+~m3f{Q0J0ib1VTNu`%XC8}48YPC;C^;oUul1gj# zoO^PrCDz;Hl|JNppZ5(v^6L~OnNr%BWtU5eQ-l)Dzxidt9O>p(Ts`D&_ehQ8g-`)ft#x4Rej%HG_yeXP&*&2H&` zO#91R=~{Q6@^9*z@5x(#8}F5S`#v6$#UE_A(I=W}rV&r(D5q-%?ASgE&MSzx{Xh^`i4Gb&%~WU-E4`KXzL*5+{jK5|{BQ$eKKi zO*zj#@{7La|9x9exq?j!CKT*ZaB*z?*o(1We$?rswI99G|J8vQoI_rzr{`M=bxL3+Dt)RD}?e>-p z)%uO&Yi!ht%IqvXxMI{c+##NU>rZjs=YsLu=BEFRDA{~8SP*Tgl6Uy}x4D|4@7%Cz zy}O4cF3DaIYFJfzIhTT>eWdnsk=5#$)*;x?7q|jPafQN=HFXDjK8+UCDPP;E*@2Za zb*&ZI_gcxwR8eHx{zI$t)J>rAdWb7{Q`>Nkc61b|d_z{K6)e}MxJOMjvdQXZMLQ6J zF%x`lrC^QGU{vTR-e)Gh0+o*UUuJ%b(A{A z+3b5T)&$OH>4iw)CU787os?BVTNa1vgb4rc=gxYGE1<<^+lqryQ&WpazCd%7#&1g? zENAaVHimrRVzCd6X1t;i+2?}sibBCm#))Var~781R4t$87M@@!^Qz&# z^Au*2cu4Do6)toW6oG&_%jEWqK`1+-AGI~wpA`Ap3I6Z)2ThLmHyn2JaY`BQ5)2of z1l>%*NI%nj7QiT1W&A3bcO++lwZHv(gtY^JX{&xrrbNrGFBAE5re0LpV3B+NUBcjP zGf6eV+V`psSj;S%1Pb-ga=lvGjU%um}pNnG?#g);Xj{eM8i58y+YV_q6t zM+DBtKe4M+{spBM=g#jx=!!1jcz2%UpJRQWb;5Eob3Md9cvyt~@F}N&y!1y%l}W=?iLG-y>i}Ve@y%Ns;(vzq8jg99C5Rd+ zM?pjz?Kb95e{8i> z>kLA1y&Jt;DKj0XSWIo(0t@;)+V1r9tybXbWFkHor4uDoTqy^&9ir;cR1%*B`yAIXMfyBDAWKB94J_63UqW&U&bNL)6L)Wt9I&nG%N!!B?U#^d4ExjT)+iAX& z))kSW8QsjRA^B+1h(&kb=#1{BC4WHq5u9S^9svfs4EVX4wv`Gm(+IYzx0BXCB zVdrY#Aftez8t=eFolrXRGp*UbWN71?oEu`Z($?pW<* zy@+0zyd9*j^i^m$!AWa`x=eO2Slt+oEea1JV00haw#u$S`!dpQJRi&J1d0Ez9z~~n zQHyh*>wj~A{PR^{zyKZHrt8FOZtOtV^BE^4V<=diF+yM` z0A(W*8Hod-otA7jEU(ym?2zBAYT*4O;@aDv~y8T^kC zo}V{!J^#O#s{is@5d2M*rEY7zy7_{Co>jq|-Id$R{+W38svEqtUAMa3qWFKF=MzDn zM!rOvE^UYyz}{ezf=Hx*2UiqBGavLG&%*5QTQwnL_VX`-lXJ_Vtj8*4CMIDEa*?_M z_gR1IY-oCD63gHPKXV0h9^I!jN`IuK++#^SQNcq=13{bwyjt^&{e+@_O~=&tyFbc=)V^ax>0^&Jzj%753@Qp-mwEe#%5;~*$=(I1txA9jWf;G9o_pSWP8gC2i9KVGw|m3)R3_l7}m%t zS1iglxk1TAxuzXmjZOt55~G}BBB!g|ozqXRTCYs%L%@v|Zno9i9nKwP369wc|Dg7s zKdg0;vRHRIXrQkTjZKbss9y;2EGJX~Q9~9;?a+RZScz^8O6?HQyRhuRAm*0Vl%2|z z6r_JoP}O<$lZ7V1bYgffVYm9AzB7Ym5b!#8>Ga(EP%96`hc;F@yC~gK$fdxM)d+nu z&N6L27~@xw=FYYt*DFhN%*_i1TFs*>gaZoWcj4ItO>C|k0efjDxT+lhp_!gGa{b=D zYNSO})ArOJ2rM%rD@rUqX`UXruKM z^~lzH%jTJ=wx2wtB^$8|^piQ|J!s0^1rlAynJ_Yf=Kcu-&Zi8ddq~`}pfcXdu(56<;=QTEZMgKR*O>E+Rp(oNBvexEtl}RjHdF9M4dfSHTg5rwu0!R7MB&g5M ziKst`pPrj6L#CVz>5W(Wj`>fFo_^S7D$Bj1QmQ$nTiXUQjDkR0X@^jn&pc?RS4h9= zTI;O|y3NzFX#_kcN4Tjw09KL$Z$Z*~F>wN<*I=oDk>M|$ z`g4~WBnvZ8gAA-POpv0KwS>$tNsz%BW^k3UmCrb^T1q>5K^T@@a(Ymbm%bY9pS1ox zdRn1PcWMKM;bb>1OoR-s6$Eu1;j~M6(=X??GJgooEmByQ3r>XD8r~B%ciW$B=!U{*dB}!=PWVXYEr86k;z$Js^@~f%^9`QSKh~&dvB7>g>F{ zM?&dj+!^@gb-Hx+{a{=lb7JRETa3;-p?INQ z$JAHT^|2S-m~lca$X2lA>{$Fw<^(IKKfo3GQQuOTPw12D^u5-dc=5ZB>5GS)^0OFm z4Fvdg#NMNC%>LxjofRwwmoDg=EPznsGe+0fL*q*eA>}KtXqCy>QiSIrN>XIN^gF1+ z8_NRUZtO~Y$}W*OFh7O#gXAYQyTkXggY(N2m_%=}H-kFW1u_R8PhD9Vsy?v&i%%4! z6s#_Y&$--^wmte|BZKVJ{UL{1YPMu!e*cetox&@NqoIxUQC)JPO8W|~QK0SVY^9ad za=KCvq6*6Qa(nNwn7RYWhw8+p^zugDz>KXY$Uk$9ZisJ;bZ|Qt7u{y5``# zu5ra?j;{5~gdfi<4;aaG zQc2Q$HbRnoIpNsU2lU+>ivp9$^!xeo5&T)7sL=td(%sc2_qwI8_pwvNybJi0h+>f4 z5Q%h9LBhNpF-a<}>6ZCy?8lk?;}}e2OyR~ycFo~YUQxs_gfZ4~n45%Tb!k4(r&-(F zVYsRj;RaS^{tvwShX~s8!oz#j8h98ojKz7hggJ;q zMuU-$H;5H5oRk}!$&?%5ZlH$?DRLd0Hcm==Q!dCrR>etQBZ{t2`vN!lP`W@SnT#_y z=}Hv?8mzp#;Q(nHvIS#={*hB*)G~MEe8vN}I%Vr%aR`SZ0m%`fp9}e)I{!Pzcqu{7 zXhzc-G3^N^{Mco4Ar(|?{HfDE0n!xf=v8gO+4ytUe?JGJmE@tQ4TTAc-F|Wv>d{_< zo+rM>UwU68AA59N=)?NB?>p-4hdmT}AKieug7c(rZAY4tYF>$y%x6Pn+qW<3i-*g5 z40^jGe3My%;CI0H?Xz4^^0oJKFd8)BT+pMR~kSff#@{23%snCfGq zg)~uZ@pG=RoarLYfxZpxt-U)kVl0XJH{o*Qm}|*jf%fL^5>+Q_*DvA3?FW;`%D}=@ zu^U;AD*_ZgwnO8*+}Y9T)1E74?SjY~vxbKIm0BD)F?T@=xf`(FEz^DreuK0N3cR48)}w5FwPI99 z)O=hNvh|_b5WMGsIRC}k)n7?l3nRRAz_EDs_4vl68*BjQwLCYLykPbozZsvUu8+O6 zG6&tdsXUvWPVDWPdo!I*Os;b1aqFAYI?j%Y8PK&_nnAVNklUk22??Vr0$EUM!{keE zy%&$amm4Gv>nHQWc4@?jQHpT7UUmHN*g`PdW0N`@C#57TG7G}W4|F=Cz`>fmJi6{I zQ=immK0_c88(Ey^&pYlpftg@a*VzY;O_Gck+WqQ|-djSQ-`)#fo|KvCZ4{&soC=28Wq4 zceUs0RchJ1^C!+D3{xmhOdZ|d_=R}K!`oAGHyClI0qZlwL# z)q*~)tI%P_67vNc%A)*>z^cymx+fbKAm$!JW$pQH*SVl30}Z{U2B6kYzCw6Ol*2)C z8WD`Ny%aMC7UWsxriYC7%Ma3m|8t94;v<7fb0jdE>fWNK-z591jko zcHuU06-?af%_?r8&>f`1`{2H1W@n*a+<>L-0guXnSw+QTt~eRCashatGbC$PRiRxY zUFjZ6Vn8#Vb}$UF9GefBUy>yO1f`lKTO;NNb&j*mL^=G?U96kYaDuNeb|0+x9Yi=@ zA%w3C?1iN+(oicb^O45(5j;Qx#QN;c(5D~Zy7!+MUdQP5`)Ald()_0`?b)o`Q%%Az zTQtb26H8h15|q&9cRgguG;pk3md9l73 z`q3#vO0vfIGPbk@^-P7V{_cCXIO9WZNweIgE#5IY56;5^lr^+?VGNBE{Xaj`6I>4E z2{N9}V)5G*;w=4>#Qr7{p5}qcaA_Jr7f(&3{o7fQ5XLK9yxw9PUNUd^*f>30GB$aF zll(z`xULxTtVNpB(@jyGt~VG27hV-k&fLgGv!Rb5+qW3I7aheQ`hf!%6r+M%xU)Zf ziRH3%cJVf1z;mZROdY_7=l0+5tbOp5>mSoN`RDSv?M$`OqNMW8% z#dq{!`t5%V5u0ur29GSx3c;AZ>o>t6M;aLGtabblBb}VDCmXVaqrDs_ns_Hy@Q{m` z%OB5JTyn#T!kdq-+#SJ7exs~Sf3Y!{W)i8OAn58aOjp4NZ1j(j`aL-eU4iRN=%r!k z!86$Di}(;q4ee!08gXKx$}6Tx>r{=xjbTdG=XL=*zI~gG_v4i1A^S=Uhu>RpJUqJi zR^AT*+#AQ=2Pe>pBj#exn9hYT0uAvVRBPI>@s-Q?@#=6qPM_N<7d7C<6ZH}aZ9z#R zq0;kryFPdSLNZ1cq`#r7HS=6Bo4r1{aqm|Oh?Hk&Pp6tVqOtpABT`hqbF(y_h$sRp z5A%m_-x*v&$1@3JiJzZJ^!WC2gURfW72y zbY?)zFI9yW{vbkddCAhu7^)CSAOZ5Yfc1y?VM*g@00&T!5;tLn2Y(&tbaUy z^Y0(^-z-$9euE-Ko;UbI{tGduUr#vP-4hJ4Hm%lS(_!noVlL}d>kcN!D2Jb|u=?v2 z+on0wnd&~&L;tNgMD_dYi4vZjig)_czaMR` zi_sR3y^nW%rCCe@!fb7LH`+H__NFMtax`Q`(7g{pvzHpAcS`ecLxeKJ~s zz8Bd*e~DC}W#S2F1>+qvuF0rsku5g=ly&fc)sF%QsgMp zW5$hQN`#(ip<$fkChm~K{wz1y77$Hv2tf#OhBQ>s6w9L~cErKB5>MiNd?9`lJzY?! z6b?nASd+w(N~b*4=`GFCVlC4K?Npr(>Y}ddzFPD~@AZZ9qkEtHqgV;#?}E?=7YY;$ zln+#vt`od)&^I}0IVzJ`Oj%j|rYJ^9c=3RDr}d~*W`%u0m>}d|Jo?VUo+?=8c{{KIEh)|THRG&Rgnjn(AIn=H9AKe^KZ;L?dDt{#Ss z5D2jEhXnMiWPH^ZVVF6jUK+8)7=-w_^q2$(@I2_9<~uqCo$RkmQq6>q^oJLa2jafx{H+FmhQQ@Qn;#pwFZerl6$(sDQqr4n^XT}-KhfGre+JL&-Yl?0mMlj9H z-28S+JM~9b1MNTLT4xnT1k%jnQKwubl!z_)nlCQtrChhLui#QhBlysnK0!-e$-Ehu zqzpq&PRKBs7}VL%4#cK;(sF^{9qg>`Tl-SOP-70t>U1z-HHK^^Hkyx>cNu{BHL=V9 zSZtApN9I%CNbt4X z9$D$VaQotgOAnjQ8ZeDjUtFEewG*dcMo!jiz`!F)lY5>~9(r8&mKJ|$tC|I}D;Xr1 z#S3>@0}y>)HZRnuE{QdX*X#Zv4-f$o7b98 z#8#V{J#V=c!~ScK@P%JHkhDJ%PMn{b@0629TV<`%Z8`S*+yY3!tH`c(71B>DQ%YHv zij|zizybwu^tlupI_osa-q7#wL*us-RVJrNpPHmLbHJCRp%;3g(_(_m5TD<10k_z! z8GW<8{npJ6!QH%(9%I(oB&HWC-De4C%?g8HXPKmLy=h`%!F;bQ4csmq)~`H&3T7BO zTHL3M8C`DZWDUlqyLZ4A7xiGK%mlyJ(VPWCNeyKvI|x)sGyN_n=PJ`8zBElQ@KB3m znwYU6urstaI~xdfZJu5+S~iNTHkhT2X5@Vp7z~I8{G|sR7E51io>M4Pmq1_6P={s8&m05vEN%|vgG5R;TDzz!wtsHBR&<)+YE&!mNF zA_Ncs7XE{V5f!r5*vyHnQcyposN4)R+hVlT3RGhQ+H5D z3xjNv+|Jq)BkN2IV<>Pmv}8DiM`qaCW>}Y34lWirnNJuOqzC}e(=!0*+)+DzyeYu& z;@Jg_VQxFIUu zel&c7FCgH;q=^E`sA3^2SMUO)K|1yk0F0ZE5AaG8Gi>m8*xk>m#44 zZ^z1YC)XV$8Me^JMG+hMn3sf$5r_kX!&tXCLTDP=J`+F3-yMCQiv`=4%tcFfj{TJ{dzd& zs#gGY6aM(}?-jZ;0O0h;MFmx73p%# zyGDMR`Lnc^SZV{CR6df&rDLx_OD=tSY3F|ldOo5+{~zr@XSi%cVkuexe~(_H2mx^L zvqgSPBnzseZmF|Tmvf$7bBHd~~F{&^o}6A0p1cc5wO)xICYY4*N?Z4t&^y5!o~ z#DfVf5ckD+Tn<+IFc84@r8i$d%n>k@rqr3_=7$edIUQmvTt*ya+br^9<%a$6F-C|V z^R*!xy3Sj{6m^<5@%}z7jzTC#!a-0H6HBFbWmN$wgh9G@^W9R`2sdYn(xxRAi;xsr z`rt-kr4|+ZDYc{Oy+?y@MI*&AXU1Z@6kpy{8%2bO%u;#dzp*KlfTJx;iJWAcc0oKJ zCMY)Y2e{GhwmxFczC()5f=>GMwN4z1#q~t2r5}6P96JV=70a602Z)^sKqp2*lY-to z#E#(9li~AvAQt&(k97WhaV`d*U;H+F++(F zv7^tq^-Ni`9O{hav`^obDXDft{-q$g#Vu2Nsxu`tH^sq#4mexZt=6cFaPwtrFl+HF zZR=d#hfp9jDjzx7NYw$XpjMYu7vdq)O(K3FCx7(v@OQ2Df}e3XLB<<(;@290iEsuE zh;5%K{Bjdf;97RUipW7ZX?RkYuTQB-$C;l%s4I9XExUynqfyCMR;8uVxhQ{N0gVp! zRJ}2cf-(`}0GcU4sl+hFXw)8^G^E{00V44XnMMz2(kTjN4HcXxiNpf7RPVBt=DAjU zAnO_){2R;4ve%7j1Rw)P=aBgzceq;#@`<(VZOre-T;J|%Gpw85Q$slC0NiU$B-*Ni z5@AZ#cbR0#08?eRB0B5B=w`H;a7)xxsvWBjQD9JP;DxT`rB6pLwhl>gr}ogZBpu*> zP^tQOVg(Z^pdfv|HoZ2&2BE%iYE2bZT>2g(1FsLN zNNLwoRnhXB#D9xkSmk1dmr1g%A3@wH%!Q8f{vjY015H_x`~^NOLjD3N8mep>mdpEa zBPd4_YIe)p*Z%dLFY&#Jp(d&(1P)?#i*Dz%Tb>t}jcQvELZnF8*MWgGI_xr=AmN&+`{vMx zY*4$PFQoEl!=m*7O&Y{Rg*N}Jg~+QrR#Rgk>q&6^CVMt*cyPs9#G-9TJZq+34y6d? zp!-D3rTXAtyaHjll?XsRdB@8oz=Z2NBy-Us^i##mt=g&PMartgL2lg-{9$ zdQqt!@`f)J(SNHUluL1n|-k$k|eRkVl1N_Uj&Djso{|gZ2mlDMUiJ41|VCI@5 zn={YjT$4W_+SJqu5Iw5vd0q6XsW%`7Ufbc-Wv=0f^8ko(3qO^oY}Sj<++s3m1#rvD z0kQe4oq65aIrI8+c+M`J#+ly$SNFJ@m%m4YkgHV|py87at~fw}(xF2kwlg-J3kLC$qj3(%uBtI4==1aZJ$zhCKG%f zEf&vSR{%%@Dlc9eC?Y{3&UdrL@(tBOCdlaHt2sX>+2=E~MDwJ8Ucc}cT*y1E-fQzg zyZ?OjNr(S+>Op=G+!tT{fMD8vgiilgiA}+SS%O4KlBF1{%o3Yywch~;9dg(aM;&uq zy#|+Ean&`~J@qfxfT6-@0qFVB2w>)OVCO_exqX5(xe@~eCcu#LR0627rxBQKC826t zsqAu*hs)lIg&}%?`0pimUgw!g7`(QBb2Ki_xIz=qJ2!g>_&!Kwq(n_&paO~Uh za0nnmHZZp2a0(0OQ_>)4!zuLKQFuH=z>^n}H$PMXf>D@6!9<(EnRCL3G942m948t%Dk8qX|#$X$JzQ{O}aAe8F4M0eHBO!=w{gs4lvE8tc9dTGYwqOUs z4m(HQ?Z=L$W7i!G5yTFJoyGJG**S1<2q=(9q0Y9KrxZ;YUcGXa=$aB;UQ4&cB@)>( ztR!5o+D2NNrdXZLw$OKZ`zY;q0$n{wsR8Mo6w#g1Na?JL*e;pK&Slqe+;AV)1Jfv; zLM-1?_V4AHmjqsUOC`G3!8hM2q?dy-tc|XaP|YV5fPgp(q5?B$lz}W(8L)yA%Pf~N zP{%8yi65I~1;p4*m`A61 zXvlDYhRn@^4F@hfY~f2`Hc}gmG^#?5)GaS`jO(dW6;mz1KqoWU#Ab0-iK(7ZCgh8~ zj8g!>wCZUaIslqM#Ho&9f1-{744xys8zYxlq`+d!DYk?X$tJd7VoN2eNDvTk+z1>D znt1ZShYw#|))By$fN%H+BxDyl3|L~aHF^gOh4^};pWJXIDbx`^8&Z8cTg@;gM6Q6{ zn&6V1FC_Xzd0r@*sGy4ZETx+DY^}KaQ(aaI`#H)<&T)k%?(-!7@=rpyEVQELe*}O) z2HJO;t`qezi% zor|vT0ijb}bxYD61K#czS26&EkgUH8u0bf5s=mA!PmAXy3R;>w{Q<;(1aoxw-l z%5TlT5kS8;ua6c&DPFjS+gyEjx6PHOgJl2!%g5dVQ2exvpsy4CR8y3%AhN9h@`a-C z<-w@TE_)qt*l`U}kuZnU>2t}efJ~WR;Xe&%bmJ=r zxL;wfkSSCOox)QQsE81Il`0jcxRy$-N~UsAncro;8~O2C&mOIp@Dym1J?b2G zRD&}ykWI35Ip>~##`^q>Mt<;*NbfU}xipU!@Z7&e-%XBg{hqA2;Z?sW?o&t=(88InfC4^s^o$AHd=yIpz#dV}P30*xjDhT3hXX>05t?f$>H+h6$Vufc2j-lRf#m zQP>E8O&H&P%4RymLzV*oz%o1N%>ECdzhRqKeu?xTfUa=xH7M}KziM$5p-P@oXZXUf zaR_Vg*QKPT=fRV=00t&zRxuLvlVP|K#u_Ip9J+%*PSH?5dCH7<@3Sqj)JoMh*=(y_ zKZ(;<@1#@z-(Yt)Jkac^XI_O+knK+IXNa@QCi{X5s2!~#E^^G+pn9jx-|rag7pmEv z>r5mD7QS92>^X4d$cZzNU|~XpiqfZEA`LdcK!c2DaY>>#erN zS~Kl)_zN88xI@Wme=@h-)Z~`u8oWR=6=5>EB3u;&X5g7dtcs0UWEPQHKyEQRbEzz& zv4YxiI;*(Zz}-eJYIxbg$2NX;@U@-4os9PAtyZADg4Bs{RJbFeoe=9Z`>$#g=Zr+> zB)cHVdHr3J=BiXzWV&mZ`-Zq25k-R2mrhZ##oV^ zcCXVL5o_SaHJhR&DK8aiPj--IF1XR$xOO$l74l3XDz61;&SVUpBaLrCz+~aAP((Lr zrZip)n9|Yt4AOm-1dtF40WHTc8e--7F4n-NsJaxy)H}?om!HTRP2c63FHN zefJ3)!#goQnDdDk*XFD{#9qhIwcivGSl-81dS1Cp`Q=3^qT+^UB;RHZ0?meU*%`PCdF@W#FJ|wdevg5gkBHF0BuG3_K8Y)cY6y9R`0#j?jmZm;1{*PcMx|-%2~sF+zvq zNVLkzBtK%kI|Yf*AOMnd<{XY`)7wZfvw|TcDL5Pb6av$Dg~D5bO=2ET*#Pimia6vH zI;9H=ldX4{wLKilrUSrAe>(-SX{mzY#7+h0+R-qvtx$~UwL-F)D1}Bf0~NZkDN~r- zr!mZe!ox}(Z{nk+?Vb1kpZoz{|NDe!EiKuciS?uW@cMsJ`TrYbtt$w%BNTx~7sQ%y zjQskt)m&XK)d+}ln1X1_o=keZ)g+D7MaizLwUcQ|>%&>obM369rg9;pY8IR=SiJJ> z<{BL_oVl|Ps6OCg>Bh*l&nvcxOx?MdRUJ!g)vSo{0GBl@^$LqjP%i*d99|fMk>}(c zDuV&M<_v7Ct*JswHc#I5%l+%4Ng%5HCtM}&s~r&y#JLM%?KQ@imTcAeYTaF`5d`$* uFfEI>K|L$!>DjC%S+nG1j9G+%x1NUEjfb_pSp#K5T zKpw!>z{ccP_Vt&3{yPWro0Xlry`7Wu?J|ECS$*EV?oz~5Qi0gd#H^#S&B zq?*}A9yYv9^i6&H0YKd7=w|}v{33s9jHZkf039@jp6APgK z*;QMz@+xZS_G-1!>R)TM*=R+{{_U=M*p$Nhbv%>2J^b1&J)6%)39$h@P-`;^x(#T> z{?I^k*o={t^KTbB5-*6;T&MVFryg1;=Y!khiTLrmX`C4GmW5OYnSgvA8YfkOijBcvoinjg%tq*OX7yF>l#>< z6D!`5i1vp`2y0|AOppGLa(AdAE(mSFC4Z zs+va`ac0s$m|M_4H5^@QlTF!^urGBrMqKKi-Z66SHq9oU@&jKcRy5nXAA9Tuag-;N zU_g6E2sK+wSE{i^WDD$1Ilg*SiuH-0NDWh?eNIOCpCf`~1^H*9DAI(X{)mUdMT|lm zm$F*a54nBzhz$8m`)kwZqoZyt1~4L-sL(3wFz1IKmS`X1SbqzGO;KbNf5x29#4|45 z<8`*K4WZT%h9-uOhurJYefBsPzGs*N4Kt5gstx^nT~okMR|<3d&)HF7T{V9^DS&R= zBSqipq8fSF1tLq42y8nzL!TrJ81Eeb?~74akPGe79ayx}C_+$qIr6CrXq??{?R1r~ zsF(c@Um%e)DBJ(zPx`)hJAnZKF8z7?KT#SF{)FWI3I6#j^r$P7k&j5s7#faxGcWc870uBm1r!Z~!L4{6B*Q3vt*Vj*nPBhxr z_XH|NMo$L>^@ZmC&ljb~TLgj(0D|{k7TQ$aq`HK}{9#}I*t>1`LokA&smIhK9?;SJDuAQVI7qAs&&d~gia^`bsGt(SBB&YL*As?sL7@ZK3d zo_n7Ew}0(rp`3Ea4lTT+@D5a@$j$xGBt4M)8M_BvbOI9EpvLSUyS=qx z;ke1V0%5z|3b1kDg~q<*Dn}ZQxD0RoqeP4_z^@6NcU(#3SuFZ3gZWU` zSTgPWFsnj3tCybgt576HM>)Bk>e8DG^gm^r9-&o36kjMWn*2hP$C^&ygru+>vFvz^ zZjTF1em`#CKR>Dk7}Bj{-dRz-9w7*C=M!1JJttzleq&kx-RqDk;A9;&^r5>SUN>tm z+v&}St7sdd-?&q;k^f)xiFqltMf|_2 zXw@E|)uz)Qsn*fBB-72zKcHNU$zqvpYLUyD>HJXdu>fH&m<>)geRh4=#(v;IPnmTb}HiKpqqK(+1-U{*T_~hVYK4|rv9EZ(yl$Nve_rIIlTp` zl&I~ZBKNc;e^jaLVmT)~wIrBih|5^V&MqLk3TLTi7T);=_T(S)mx6U*J#TT7ucEL-3HTn6XZJxVArp5;8pKV?>g^B?(XTy<*t2K>QUtV zaaqf53%G7ZfEvt|LS$`m354Z8f!biC_Wol|C@(@V<|w;j}}HWdOZLD z^}pYg?+ysk5A2K%fDGJ6?DyXz@qdpG16HdISFSCDGmyl!kLheykKxnvEmFB`W;kLh z(i7o(4bnWN`#0wy-x-?c7tw}CrpOYiv>x?m2#%lIa=mA#=B)ut8&s^&GUR(Y`()wZX(xu+@HXIYyl`Q{{8)JaFpf~xbC z>NZx!G&M<2tpcp`q^r(ZW)n6!HZ44^tFmh%odz#g89vQF(#lJi8{E)eKQ?gtoeU{n zYM~5F6|I@?Sw?1|^G4U6D_*fAiWsrC;ye)#ALn^heswH$Pjx)kC-~h>K4~0Ld|~)X zg9X8i%*wQZ$>v6Wdk!&0jj;Rajt5G%lV3*HcnYqPPh;m`a8@mAK%d!7a^YVPOY*I} z`sN7CnKR^1(c`&wiBo-LoBWYRSv)5Kb>wfEek7DO&|RENtXg*C9(L0Ksx^V@1K%4` zJ%6R2Q(q{laAP|U{_1W-S8?5>h{g$oy<~*3_$IGUB-6pz@+s~j(cGR91JCOD$|>kO z>fgVds7hE!OpGa25$Yv$h_f;RG77jBnDTJ7)S&J@@f;L;Je)J+{>$`Yd1>sj5ek|L zxfN3FGNCY~h+}n1BjhMG)Y-_jHRc`tYNFVCp@9S-TduB;zqYAzx zcU~Jpxr01GQqQFDKH<58<4 zp0*^*9OEljbzbj`*E2b{xObs<=xbs`&z3n-;e+90E6`L?&r2QJbXY&55LH~~fuou; zitppP6z89Ee0QuNjy2-khMrx2n|dyf#~cXQGStO3v+c$14rBCY#RAm)mC;|howo*D z&2)xWV6T-633#9!JG>9EFm5G*@9`eTxymD|N4eG%Z;fkzP&Qhjn56a((PWG&*W_>e zve6Sb7E^~Zho%AV%mdvyo6!U)v}c?SZx=nunOvbnLYUJizR1Hth;sdyMZLI`>UAHl znr}x~W@^}GD}qamX`;4aq-5$pAiTZM>(-{tiKhTNvGn{W0$PNB(RiLX)E-B2S7Oo1 zk_2^zO(36oEuC;S*y+n%_#SCkj|=(gCHNb?w~x9g2iKqL11M_h6;3M4c24(_p|tZ| z^>JuB)T%OHMRmm_3DM!U#1U0bY-*ZsYN&a999G)U(|l8T-y7Xf5W$wOQZSDK-xgDO>Sfs{(pJbhh&(n1LP_QJJjWi8Xc^OZ{vxz(x!vTj0 zG+PanBBqnf+2_IYi6eT#6R|Nn2l`Dzk*Gj$wyGr1Mev%a);Dz|=ptD!#;VPNLzvZ& zU@V8n0ApQ=Fwg?-|JFp5VPnI#k4z)P!$r`8oAxV9`>Rv;RiKAKEb9OS(Ic2*u%TcF z*W{;&FpqL-X`b+#htSZJ|M`2&UzCv*l{YTs`kk)J>8mYz9Nb`{kpg=7{-tc%&q%GF z`iH7PU;LH~&{du`XzR2om>4zYJSqnJlqnXb7SH^ zT1rq{k|xWxpRiQ=S9YDdbgX>?eQhxt>M+yv9F2xrTxLUgII1c2suaRZ?te`avH0nvhEN9PlD?<(`)5)_tXa?g78kX88&Kp zeqP(%rMHMO7|zcwVXA{2Faos*y^!BOGAZjhKr2JyAOCh}8r|*t$y3p{_JbEyziCB2 zOqN)vrn0bjS*c>NlIv~Vl-m&NE!%PvJUTxG5589U^Nm=idSeLlNIQsBB^$!dLx>>X zN2@iq=hh`Tv&8k5C`rMgK2U|-^fBhu8eR?`7);;7pAy5V{bYkP9iKijvHKSoPA1)! z@-69ezY4KSA7oLE za|i>9!GIYsJ64A&fPxL-q0j>DHy%d#;qq3F8#54mhnj}=K$>`0^hjNCxsLF{=5Tfk zV7&}j+Y7KxHZ?|ju*2QYim4(X8@}YjqMMSBgFN32#bYD^Z6w(Ibh* zt0MCaG4JOt4`>xSzMNy+)2{Z#*-_&|rPk`!&-HtySE*cQBuvahvZkfjY%BK%pmd-9 zt?h;z!R+P=aRieU^qcs)Q#`6%3fBvVWpESluQ|Uy03#Ee4JD){o~ zRKCs;Xk)hyC9C@M8IU8XV|9^Jrw!uF{m#YsmzT-Kmk?JDDnk&Gx2EE8PVDFF?EMpd zh;Rk%3qu~Ze!XCbW1Jw~0ow!~hwHQZ`KAY(-3U^(d6vllWVPDx3|u}nq_HGTn@PtK z8OF~1a4=Zm2>zHw_@?Hl-u?jfjgEnL-(uUKyZ=K9j*IyFmI?seb%w=V*xJjkA%~ly z)h6z$#U{otkushI#D_ne9>LBljGW=RA=PF33D@DKDc6nnfdEVVHJq3NFX=f#Zf%q_ z?}M;DbE?M}3ZwB5sA?2U^*yr2`T=Ld=L&1*-XG`ku?Wxm#tibZP&|V1%J&`$?rayK z^KBIO`F#oR+c2BWlJ2>vr}r> zB>hA-@FdqE{R#UGI2yLgq(iPlf|M-BS?~h2eTGP?dg*?26L;A-RPAj{mA2FNpOdz0 zLY6e`V-mJ%^%m2dtVN62Vv~VVnja=@Sb8sN1puCx>FLR9yDSIHrdEWd|6O@gmD_~s zDf29~z8P|X{mccXI_lw$3V8@qX+Gp}ANOz<#Bd)4a1*64&yV3JQ8$heq;Yq|OB22! z(?gaJkwhEN3q_FOhl~pk&ZRyp7eY!v>!U8A58Hb(1fB;!niBh*Mir3doCc(vIG0jE zSeubyktd=dE0NP3p;#TU;HV3zco5kg<#eUN-7E0!q0{713^4^?Uz%c7tqOCoGR6zs zi}Z}Mz0vX=mVGAfL`GI(!Yo!Q)j42Vj3SdVr8-EPaWiEMDwEPDSWM2kpB00HiUEZr z7cf4V3#ySeM#l`kQi^vOOK?SbAiU6lyAbWJbYcq-kTV|^Jf5@!%9Z9K9JOhPxE|Frj58y>f|+v#S~1%N2TV@N|D zgRKPpSV!8JZmj0IrstTOeeM)qTw-`_Z8tM~%tch4X11x;CS6>Gb~M;VX5GYgPF(A~ z40b#1biY*eMAjW)y_xnD-JE@VAov#M9iY9j_-66##(hM6`?-W7k_O`pxa_6c>$wwq zW044-&7GRtI@5E0hT*&WHxhvZ0icr=<%-mO@5Ek>tp2|uYNOQ!Z9@WOVJruK zpW&LCY!^D+MAbuU7Z={7+O3K=@Xl1+9n>dc?|_jAcY<^=@|lRM0)H}E%bUMSBG`mB&6m^VoB?=W(6@?{*CuJrUg(BS2(x69)4eKJ$qyi zOz%ry@4je$jeJW#IL1)pAUS~*{hhmB#F!KaZ`fDJISA+VhU^^NIKBn$$OVte$&v~j zmC`Kbv@C_ki=mu~Z0ABn7ThwW7R~9)^R}E4Cufvf1!6xNkFfRRiN|&UIT)8qcZ*pl zZdW+M!V#1}k$sZ#jOD~43B+W%_Q#Wdo}#fsnY==w&U4JB4W}U%Aj;DRayUjXt2MUk z%wDd4if;mPzFk~gY;5Gh&MOP!PNCj&3)kkfcQ#iyC#9zx#Ujajs-{?*3vZC)Q z{UqZRQ>I5i%vI9zpS%|g2-`>9@Z%f^(^x#+T_s5q96YZkl{eJ1F9q_0Y}qkHOvC{!eUAg*%;yyztyILl=Bmj)vq5#UT;LxV(KV-j6ukKX8yQi|`{ zmGwT3}!Kb3A`FN|4Pw8=0XX0w?IZuwOj{aIIHGh8QDUX!Ei8#@GFU+Nv1JD ziC5LA*5P{|e`KQjT8%n4gm1Xx%Mi1IXT~v|F_t{JSkahawA0WNVqS)Dn;T zw_ee6nSi5IyR7|@CRIVvOI~i}P!EC|N#_Y(NJ)b)R6!|lLGC#D?ntUo;xY%ae|767 zm#DcSEF{ktWZN`wPTjb^4b4WXl&-R(JixX}y*AifAG;4F7CUic70sLVW`LhE1fG6Z z15$In9X8#lh*>F%aQm>x-s@U{GV8B1Nq_4K-^>_AX1RfNi$?J>s79@tOFu#^HUvEdQ61vJ@)q){zz$br-I<~$}l|w=f!fD7w zY9s`k8n!1wP(70wD1^n4q7;eo7hkZ1@w6cr%2Ea!GeZJ*bl_&0zcv)5B_Nw69)>0p zJxkyXESR`5K=!AmIm<=nDp@3YKDLpUVHuHYXgIp);}Vwa?}_ zhB7|-(lB2lbRh`Bx7Cn|ZGgf|(*LczG54cMM9lb;H!<4VH&eABuHrg4-FQ>KC~ z)zXBJXMVtmex6Tuz7WJtsQhOVe@X)##*c+pHGOLw~&FrpG(o zQNZ^#wux1!s#xP}7pOmtGW6tU_z(#^kokj3jgBV}2V_Akpp z+9`cesm)kf=r?m~?ECC`Ym3#YrJ828l2-kaEk{{u!62WwxeqcHBh7cGw$K3E2ySjl zL&iVr18@Nsbh;K&KU#cyJW#0F=W7*n$UHEe{#HkB1V4jElz1}!EHBJ%i(M6KBBO0R zgA!p6DgnIjr;0~efo?`_lgk+<7t8MYn&6n881CCGC$rNQXia{x*LieVd;0VSBID%r z6N9QW1^C8)7-fBk5J3uXwegS+4j>2gEK$1J{ObsJgk5ojr&FY}oUuv-0OPCFt>X5qsP&JR01(d9BCTSpL8!E{aU1CXT6lB-S zaI4iU=(bV0l&XKiErU%EKa?Zv_-e#UEK|RKoh&he(DuLtcS8-aN$cx9v_2cc(^MU7 zjnbAx0Qy$qjQqJ{Up@~pvg~e)<)+RO7b&6YVrwRoR5Jnd!m=@BLB^07UiBYJ+THIU zbx7XZrw*KJIAm=@*C)>oHgHeW0e1-b2mC=z%#JO$N6+38-{+Vzr;>|=)+Z*U)&YtHg|M8LdrURp49R-CpZB;+GBio-=SkdvRsq8X(0o+yr`FqSFJUq5VaPrM-pfHwlw)i3xt(wSl|{?gIN(JGiYi5s-M zigue0m&JWnF;y&*SP~8UR$-ul>dswoo#sb>&-NDU5qi$8|VxnZ-TlsT@DUoLC2ZWeugp2Uw&O|8X?9*4M6XmjjgT~ z$(?0h&Odw$YNS(E+d||&z88P7hX1%at|fi!e&6X{tkVdm9lwNn<-D*IbYgK9vV{f^ zMef2F;N|lq`-{QG&sH&dsq`pjjhf*Ld{uVR@qMENKPf~$yCw~7gn-yCV;Y)&&<9d2 zZTw-D%FwzX2#ETlW3LzrkTlLNO^&~?#;f8W-sjj->+c%YO+q8#Rt{cZ<)fjIAq{I~ zVhRq(2UFacB)e=LW0J(DVJ)`vLc*k;H6JIFL~I33L{U;NDVcw&a0MG9njzL`!it|% zt=r}~MCn1h6JSZll(4Tj%1RF0cfjrm-uL5(_$qO%1O!?=3O-_m~0Ct?t25zF<7Oc_g>bJZ-7o&MR3sA{!*@HX>lrj!_W<@C! z4M1YDX#glC$w99hJh=~F_&!r0qWlzQO7K|TGDa+_jw^^i4V%`MglsiS zTzHprDW$qrLGQ%cPg4OjsL3Tms5c9Au^D09)VNtldkhwfos~D18dMJ2bw_62`Yjh2 zDkjHorSUda_)XkQiHmN83a0c7XG2&ax!Y;nB}e+Wh2dgj&?(-ee@*bBO)t_G_qg7Xn1giH$C&VwHB58?Go1{8$K%B1$uvvq z7E>8=cl`qMzW*+$<2aK_?0Fm4(y-{!I-AuqC!E!m09hw}V^+02SGqp8+t4cPI^ppr z^cllRc1c*NK<8(hz~mSiP}@{lHK;#bXtMgE3?NWXgUeh8YBlmg6w;ci7K_GTn{}{; zIsQo2yLwJj$wKcwM)Zv}2Dx4lqmNW2n57i!Y#h@HSiG905G$Z8kK32{d+WXfhF-H6plDa$F&?e zh8xl_TnUIj`z@XuA&t1wK z_>o;P{D=(R8Y@E)hi-Ckx5xwjA?X34Aee#?YkB$JW)$qHdRYM}UR+YgPl|`F)J!T( zZxyiHel3nKi?zm3Yb$&Y_+GRTm@_SIOTqo_Q`VLH#5y|5P*<(Vc6}Ld{Dc|pM+IQv zwg9eyzR9W`tfg-o9+DRobYBqsvm)U7+8FEI!iMMr(L6r^v^2r2S{ZTmf@jK*7FyA@ z`O>rs%R117K zmuV4~F%$S$8^~H1l24qWD*IE&mb7Q(QwL~gSiCz|r2c)J#sxEbvIJg%!d#&<^CN+I zz?-%B{i<@kN-7Bw`j4JTHD5sPGQO$@ka{6T`%^z0sUXBMm|gUUu(kiTdLU8(;JZMf zw`y2v>@0L6{*j$I2&sL0R1E!}roeiPj#0u`e@daNHf4ihHla=L#D?#|$s$-1xmX%) zQiYe;XZzUAhOy1Udh_TOnZ*Ss=pByv{bPpR&Ql6{qgLVMN#trOviu-f=&ZDN7VRDi zjLn@><7ZP@7Nnxv0QdmB*s~)Y{kfvL4Pdp&ElRV~cU>{W0G;lHj422>+pBnVl{(Ba z!DjwmzCcw(3M~SD-xH<=bbSpJ$#oHRyl_Rq?rUf~KIoK$vT}_+ACFz*S2yvmvr1~u zIaj+IKLLtublo3pkyj#YXnMypcc5z-w#(6O@m&d#61Bgt8g4y3LyM5zavM@b%lL{^ zq6rYSzU#;PHz^r8O|^I0Jz@63=chZzMo7;vC8f%@V&Ee+)P%-jR=~@?LhSCTwdy{8 z$@ZnfB_!zg!g?BHqw5iHvfy>3wlc6p)FJjs2aY z6}uaQ>S3Dr*wa|`tkj{QttGN#&R6$-?xm3}s8WYl!5;d_pIa$AkF1(nF+n4o{X`TZ z1UmaxDC-{-N+J9Nz&aN-5FFx9OK>C8uf_m%=;;L!FfihH;zu|&YFbV z?+n5DZx9cE0bIt%E}u`-s-V0$Z}P<>enh$cH9kTn>QNtqYd<)zVbmS2j46T2KE`!&zj@F?^5uQw}|d z@zfCszl{g?iMQ zpwR*GKG_A^8nIxiR#yEJSVJueQKV|>MAVtTdp<HTLlYqOb~9oVQ~5b`~xUvQ++d7Bu{$bo#>?xq*s^dTr~rmTbgc= zdnCgPtDrYr_#Hq3LvR1^35HWNg3^Ayn3eT-x=u2?HL=PIJTr6C~EI#f-oGie9` zD9t#Eb(CX-<)<{|vr=KdTH{EmPiR8f^Qtq<&sULcT30GZUbrMe{n!f59Kr@>!`03y zh>YZ9g9=&*8J|jymg9^@Hu$%GLZ~$t{a*UnYX6a+ZJHd(^+uL^$qa-`&#)ZWi9gn=b;3ib zZ3qx+)+$G7^%1r86YY;t0~0RNXDS(9p2tKxQXCAfTPQ2iq((~TA9J3UGZuW&mN3J3 z$r;>rC#M7^S`e>Zr}_8_~LBJ5_@Qapr{@6#*`K+nL+WJ@VSm#$@A_xM7_BqeddFOp z^uA@2%U(i`^cESanII}lqFBPQ`Y^zg_BlXg7BzHX$LJgCWSXTFLByK$?HTx&fQ5Qbk`MbMtsc_rCj3irCmTrCY(a882i}d498d(MMwF~^%54Wj;3x&cI z7UTY@$kG&mFNyRD%w3{&^0M7d2&UbU=`;Z%qst4z!)*Nlo&_Ri1|~fIQq-9WmQ^pY z;kpX{M7JS?^!Bl#DE}UiStSO$-K{vs_1T4;x>;kFEJ496Jc!$qO}?Vd?z9_ucAdbh zLvxlP&=?L=*Em(o`M$5;m(fQda-XoVC}1ej z6Xfvl&N!P?yI7PQo`-oLs9FO9Y&Mx54J`EwLxC98wmsXtFKe3PY+mnk}tfw^puODpu}>1$Acy3H_25 z{|pRcv2`$hd_frmVm|M9Ihl4ozMgeWAs)mWAHv3DRvmfDnc)1yn{Awn*q7E z)jLLG$u8hZUS0f7ZFz^&jB=AAg;6eGoj8WnilPd{s1PfU42U%ef!VuaX{N3^W`@zR#O2Q_VZcf=J zQO-uoljKk+ofq-bDD;ipwOhyQtSJ$DRVVSH7+#5nA+%B5W&z5uOXDpZFPBz@*-)LVBX2{O|S) z7M&nEy48ocyBpPJ$jtIVE1^I})CRFNP>Oc8rXAMiTvue;_RcN%a#s;kDnwgPuNX zMLOUp4sw`6RYI!+Tp2w3^J_%xfjpd`@C;3@3&fPq6<_2jbK3paq)2l#iH7Q|Q`iEG zD7x=b@_&;Z=K|9!?C15C)mW3sk5a2ZTl%lDV<93E8(k~RuiEJ1j9Qn$N`uee=JI$r z>@TWNziqwrN1%*a-mAwzwn%UZ|vvsBvvsn?Kq`sxviiD)!R zsr5kHCs=6@8r(DVze^T=Fc*Ic0=}`^OZik;>#7BUG8@-mFe!hMT-jR64q2;Cl;}c_ zw2&L3<8Ypy8>3Svs9%H)#^5=_Kw$%5-(Zc@fd=8I!^}t~nl(=9clMHn{!D1J|3f7B zZYAM2<~-&?<&1U8zGB~T2sx;W&BB&r?{V7C30EQ_VxbgG176;p~^|4O(wYA33P>DbWbk=+GfNw(_$NKte@8CHUv6*rhbJV&Aa(L{{FP0vrmi_e%dqz_X2OOW)_NJ*rt7qDIC-3X{YK1F; z(n=U!*!}L(6NdYbbTdEQLZVJ6__Q+qAb?tv`fdcyH`0CWk205ZIN5f0w{PIgyu$K6QB=p*R4m-yqi5v5&O?F~IQ4u6>?Tw`?6wNqGMI7x)8@B={xfy$b zCbR-8NCx>;ynnkbvoz>J5_JS=5o&B{#@=`CPs^7?Jlo)E{-_)GOX$KKX*s>MHT4Sd zx>h^;Honiksfl_qPh-nH&bF&Y+23z!;YO~-P{fa*TTw~Z+6;L-m^XA7I@eI4^=`nE)=Kky|AnDN^zk$8WIX8;RU|BfeW*w)#41QoCjAb!L1xeiYo5$-EuDpFZea zrrhzAHWZjdrr6==eTHF7+=8&#J`D1N#lQy+lw1Z(tiU7`K+8H(L7|zxuo^Ozc54Lh zodO52=kqO5-2|qK0z(X9fLdBq*{ouXkloyrOKqb3J^+VB~J-LCvfk zU}MrPnIS=Y#Kz91mY5GKc(J1b<@0u&Hf-kVXUz0+rXVa`#_p-wCYx0{p-0Z zlYQD4eqIg4<#~o_!@nr2*#vuv-Yu3R{y8~X6k4##obq92C>1<12#gn-9T`XFBIv7R zye{;wlH^DS;T7aX*=tMGBW%zl{>Xw(qDLgON0c2FZ%%=ah~|yb$FqjfjfeA?#pEu4 z`>=}1O%Hop#q6$+n^cZAKClQkEc);rv!D@mncOdp!)klp?T5Lr{VL^)?X{p~gOW0< z$pfnT^C@#R?L!hieCm{O1J;<=R?D>%MEe<9W#tZjF7HNiSXBMP9HW5r1LJ?zP?JXU zTaK@E%gz85W>D`SNHX`LMh7OG0^_O^Ui3d;unUIs=B7S)?ingrb1Zf&{ zf`?`_en%@7JI7Cdcf6gt5G_L0_NAJB#*{FVCBRxE49p{1a8~G;Dda$|o{CN4Y{22f zlpD$BVDBBijKEDZTrj|gUGNQww+h?yRlbM;vo4qkOmKj}f-_ub>`sBq^Vs|AgF}Fb zC66CoGjPm_G=6W7Ax+NC{Ka}tV;1U7Gd;bj$9mto&KRUSRi!yZe1asWh_1IRVHFT8KEViLW%MbzdVM7s$@-X#jW5nnpNeKc8 z3389s5%k=*r&X2r+!vSSOWa5AJ~!$7h?)mq&r0`FQn+vu?&woDVDD7EMX$S0r%yZg zxb;&8rrlkw8vjz$u*(=VNS7N|;t@8yU|BT}>S2kqTMW&fr?(~uDFN~xPM=U2Kl95s zv?+s7*3WpGe4QE-kAF&}849&=6>(Z}cr3Lp40{IUSqWJA;bYbGhy4A|Urr82dh_gSMw!V-H`xFAr zb0Et1HY8kxdXd!i9GOg|uw1Kakqp7yPb(au?!W&&npOWKV~HVt(Zpn|jZ98XdYeHq zF)ifkrDtHE$g;v-QDmpbBFmb>*@PT0)Ut3kn+9pU?D&0|vMigs#g*>-=qxPh=;)}N zBVhZ_wT*50|9kOcw{nW!@k@&ZzH%!9e-Y(7R#oGB=b8Gcs zGo8xiy4YHETxf6FiOFI6fgO3-@?Oa6#=`N{=u6|X%Yu}d|S_$VG(gC}4JoRnU>r(yLu4D`i^1; zbT)nIJ$2dtX@x@{$#|vbtuY6AE$$rP*(23#8%EMh6@ zDwUMUuGPt_g;RKGI<(^y`j}`U$wnw^Ep%4xO@o=1>`L=Nr_i#R&tUKjUmce*)64N} z=U>M03uyY9NOlgXF;R;ErS~gz<9VrXK3@3bt+khiyK_O=(MOt8)u% zYh=r8D{YHy>t#!Bi~DcM#x~9=C;F3|Mxf87g?8UJN8yU$$QA?ibmd~Mtc|pcv<%P) zTM}*IwR%rVMO5=Y10kaV(q>se^b;pQ()W1 z(7cbGyPbem?Ad|f&Zm7(5AmB<(NZ@Q?jO1Ms+vkVdQxyPE5fedR21P#RL>1Z>$n-q+PhG z))2cEs3aGJccw%nQa4zRcB9`Kuv$KsbC)}cY?%o_d+Za@jp`~bKeeTLp0$Q{TVtvF zIgplSq%@9+8PT=W^mL+DDFsLOF7$5W4LxqmoiCc zN!hSfZ!609EU!H3KJl)szpFJIWmu<$$1AQ8o>N9vp3Ag%N%~|s=!&1AEvhE}wZu%Q z-{Cuok1>KM$Rwb|PUG3Pw2O1e-&$)bK}f=rW3q+$apl~2yFXRG-WWSgStay9YH%Sx zDATG&Pivz(pn@aRLoslYrI~MwS#4=_;YXYb3i^n!GGt z5xywp;=c9V0sJF|gV9wb)faH6`uB^i@nQ-@`k*m!|0@M~e5{Y7N~4NueQ{ z{9=*DB?U`k17bGqh%I^nGH(VmpUz4K0cVW5l%;6&blJ+vfp3ctjn1nX~pdUW}oFsrr6Qid%gi2-O!Zt6Kz+p&{XBEO%MS; zxkXp+rJ;xYT}4uhA&1xtSgA1X+fPwkilrt+q$R!Rm_||+IoYp=LX^gVTH&ueYIhuJ z6Pq2;p1Iw-szPX2+%{o>G==PZc5PDqNzGHW1vgKGZ0<`ArskHD+j_Dx(gNGX)bwaJ z?f6XF(3N*Rs8-<5{v5@W6qa*X)7OUTW9M^*N5+draYJPsSxJ}Akjq=1>2MVkk)8lR z^p1l!+VClAHD!>{Ln$@%`{_>XyMUSMCtu}wK9i7WL3LyuWl=*V`SgS0&m!lMO(75A z4`1NLJ!K#IUiRFmYQ;U>q*fA!M)}&|^8>YI%?02|+8Sttp41}b0Gt>=beqv;yFGg9 zH&V>5XqV3*m_ncWCo&SirSzr5r5v^-wk-CA1ET|}1Fr*xLf`<*AW$I`5d&Ud1Uu%* zzO%OUn`9x<%AW0JK#4p2bdNH+M33+%)t%g6(hwi=45A&GFWK5tH^H0h9Snd6)SY+y z)(89b=5eB*wz^1As>n?L7ia4XXif;`?gISST%6=1sFWO&x5Zy za$H$#sch+NiEKITa|J?Md{lUy!EXDZkioieF?iIOKcT@<5f_nat@%i!yRihjwrigB zK_&jT!VQf0z9SqnXlW1^kqS`Xf?rlcFdpCl(2;w;nREu4)a>?qH;3lc`F0M~o9A^u z|CRRYhaJob`2rOr%P!a^EIcQI$Ep4Y-u_gSy^CjbBoKTWTGqBdxBu-80CcEi5JrF^ zs8(M93KjIFbysbO3T%joAF9LgRvGoDOv^B@bc0{ht^06oUt@o3NKMKMz$7eBiPY+o z^-iw%tMpJ#l1tC=ulmDQLZThv18e-J!X53ruim}scTb|~JsB|`i3iyjAJK=`m<`Ey z@vBWp0ybaB<>%D1YNJq|J6#O&(Z1nC48`{5e@ zmBueDEau2)X_W=66i*;lV-40~9eS`HHN>dnFKD0__AeUg0ap4W3gGCO|9YSO-tK-z zZQHgH)^$Gz_NfM-1GInR5+oBmEc3N?jUn9CAoTFTlMv#!mo zVT-Vlt?X~(B(bML)d7yh@nO)3&Nt*jSDNlRPesc!KC-?-IhudM-=X5)P)(IIoKH(> z<+LG^dKyV%X*{*kylLsQOj=f~^nu!=v7cqNfz(`V^`@2_>J0c+rr26)JuW^hfESWXPz(m?=u8h5^&eR5mMA%w<6p3xz=oTSV2OmQb^l6;!NfO@*~W$=YGa zx}mV14b^RAGYwmWrmbwFXtt|&QOx@vOE=M?4!||b!cieDR7|xq+IzPMUe@Q8(4T+FfH%V=Z+Xw4_kCn~-hA5+ zel*ojq3zc&>d)|BDP>`lF%*Qs`{M4n+Ye1LN+)Ou&=n7+BKw*SJ z3WW>`ITR)+6n5kL42#TJJeusu_k=HAP$;2LF@Mec4fD6m-!cEf{5|sz9|fKNqoCD~ z3pxu5iYO?epqPRZ3Q8$xqM$4&D2Lz<1r@L>U{}CyhFuA}9oX%`Zh_qn?AGko9_$E$ z`_xoW(>^urP*VZNeKJz=k~npw^nSnbm{MRW##Dr<0#gHyMjVYe8gbM^euDf6`3dGD%qN)75H2BHLAZf% z4YAfDOIf|bhFBBpu;c|}0-=Qf004Laoy#S3oKX;l;dkybqbs9a(}tOunMsBjR8&+{ zOgJVDs;H=%GFMeqRaMo?(wytX{_qTZXAr>8x$I%eE9=_{PmC-~aT6!NpFbGDM+#3# zZ^d1*%Uav-Qd(Eidzbo#ruw^dwl+1~WwgEI-+rRKweBuU_D=BI&JeJjgP`r4gtT+u zB23(F-9&8XA!>6kF%l$4MkW?mQ`glEbyM9^chn>GnR+=kHaWwUdaXWJU#jobuj)7T zyZU2ddTfH9>MuYbEhQ}-s=-B&B)54?$|n7|0mFTs+D)OY`L@>D>uQ8X-8t7&rCY&}kBc^XIOGkV5Zs8qI~YWYr4F=fkXAr&(n>e4`H0}se&_%67ct6R!~g&Q J00961005SkQ4RnA literal 0 HcmV?d00001 diff --git a/docs/.vuepress/public/fonts/Solina-Light.woff2 b/docs/.vuepress/public/fonts/Solina-Light.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..3566766cf5d83e3d93f31c4c49eb406a6bcfa235 GIT binary patch literal 16344 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 aMlDuRruCI-0rUb}wj_)C#52~H(+F1;1H&l* literal 0 HcmV?d00001 diff --git a/docs/.vuepress/public/fonts/Solina-Medium.woff b/docs/.vuepress/public/fonts/Solina-Medium.woff new file mode 100644 index 0000000000000000000000000000000000000000..e9d8fc9b33efdbd1dea7f9b8362414273dec39eb GIT binary patch literal 17684 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