From 01e5a5fc08739f04dc9d0364ec65f76c41c8245d Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Sun, 1 Nov 2026 05:42:37 -0600 Subject: [PATCH 01/29] Fix: workaround dist install bug. See https://github.com/bjones1/CodeChat_Editor/issues/157. --- builder/src/main.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/builder/src/main.rs b/builder/src/main.rs index d579fe8c..91d39e22 100644 --- a/builder/src/main.rs +++ b/builder/src/main.rs @@ -398,9 +398,9 @@ fn run_install(cargo_dist: bool) -> io::Result<()> { pwsh -Command "Set-ExecutionPolicy Unrestricted -Scope Process; iex (iwr 'https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.ps1').Content"; }?; #[cfg(not(windows))] - // The original command had `'=https'`, but single quotes confused - // `cmd_lib` and aren't needed to quote this. Note that `//` in the URL - // is a comment in Rust, so it must be + // The original command had `'=https'`, but single quotes confused `cmd_lib` + // and aren't needed to quote this. Note that `//` in the URL is a comment + // in Rust, so it must be // [enclosed in quotes](https://github.com/rust-shell-script/rust_cmd_lib/issues/88). run_cmd! { curl -L --proto =https --tlsv1.2 -sSf "https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh" | bash; @@ -415,9 +415,12 @@ fn run_install(cargo_dist: bool) -> io::Result<()> { )?; #[cfg(not(target_os = "macos"))] + // See + // [https://github.com/bjones1/CodeChat\_Editor/issues/157](https://github.com/bjones1/CodeChat_Editor/issues/157); + // remove this workaround when the upstream issues is fixed. run_cmd!( info "cargo binstall cargo-dist"; - cargo binstall cargo-dist@${DIST_VERSION} --no-confirm; + cargo binstall cargo-dist@${DIST_VERSION} --no-confirm --git "https://github.com/axodotdev/cargo-dist"; )?; } From 73f3ec0a3b032a59a89fcf1b24a3ef0afd2659ed Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Sun, 1 Nov 2026 06:59:56 -0600 Subject: [PATCH 02/29] Clean: bt fragments / use. --- .github/workflows/check.yml | 1 - docs/design.md | 2 +- docs/implementation.md | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 8ca65126..14e15d7e 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -58,5 +58,4 @@ jobs: - name: Run tests run: | rustup update - # ./bt install && ./bt full diff --git a/docs/design.md b/docs/design.md index 9cd2d31b..0f9a568e 100644 --- a/docs/design.md +++ b/docs/design.md @@ -29,7 +29,7 @@ To build from source 3. [Install NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) (the Node.js package manager). 4. In the root directory of the project: - 1. Run `./bt install --dev`. + 1. Run `./bt install`. 2. Run `./bt build`. 5. In the `server/` directory, run `cargo run -- start ../README.md`. diff --git a/docs/implementation.md b/docs/implementation.md index defdd9cd..a8f45b31 100644 --- a/docs/implementation.md +++ b/docs/implementation.md @@ -269,7 +269,7 @@ builder.

`bt` (build tool) script

+>bt (build tool) script Misc topics ----------- From c6b85f103c16eaf3a6ac2270ba19771399561b3e Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Sun, 1 Nov 2026 18:46:47 -0600 Subject: [PATCH 03/29] Spec: allow cross-reference content. --- AGENTS.md | 12 +- CHANGELOG.md | 2 +- README.md | 27 ++--- server/src/processing/cache-spec.md | 163 ++++++++++++++++++++-------- server/src/processing/cache.rs | 2 +- 5 files changed, 135 insertions(+), 71 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 30d0f453..e8601aa8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,10 +61,10 @@ project: 1. Assign a unique id for that section: `

section title

` for a level-3 section; in a code file, this must be placed in a - doc block. Any HTML element with an id can be the target of either a - hyperlink or a cross-reference. -2. Refer to it using a hyperlink or cross-reference. For example, the following - syntax links directly to this section's heading: `[Foo](#cc-sZ0Glsgjhu)` + doc block. Any HTML element with an id can be the target of a + cross-reference. +2. Refer to it using a cross-reference. For example, the following syntax links + directly to this section's heading: `Foo` (link text is "Foo") / `` (link text comes from the cross-referenced span: "Cross-references, gather elements, and fragments"); the same syntax (a bare id with no file) also links to any file @@ -73,7 +73,7 @@ project: When implementing a specification: 1. Label each doc block preceding non-contiguous section of code of more than - three lines with a fragment placed at the end of the doc block: ``. 2. Gather these fragments in a subheading following the specification: `

Cross-references

-Any HTML element with an id can be the target of either a hyperlink or a -cross-reference. If the id resides in a file within a [project](#cc-DscjSxRZHF), -then any file in that same project can refer to that id using a hyperlink or -cross-reference. For example: +Any HTML element with an id can be the target of a cross-reference. If the id +resides in a file within a [project](#cc-DscjSxRZHF), then any file in that same +project can refer to that id using a cross-reference. For example: -| Source | Rendered | -| ----------------------------------- | --------------------------------- | -| `[Style guide](#cc-nNZ6Gs2uWD)` | [Style guide](#cc-nNZ6Gs2uWD) | -| `` | | +| Source | Rendered | +| ---------------------------------------------- | --------------------------------- | +| `Style guide` | Style guide | +| `` | | In projects, each id must be unique throughout the entire project. To simplify the creation of unique ids, items assigned an `id="*"` with be replaced with a -unique id, such as `id=cc-DscjSxRZHF`. This autogenerated id isn't automatically -saved; you must make an edit to its containing file in the Client to save the -resulting id. +unique id, such as `id="cc-DscjSxRZHF"`. This autogenerated id isn't +automatically saved; you must make an edit to its containing file in the Client +to save the resulting id.

Gathering fragments

@@ -285,8 +284,7 @@ participant explicitly opts in. See the [capture token setup guide](capture-token-setup-guide.html) for more information. -Supported languages ---------------------------------------------------- +

Supported languages

* C/C++ * C# @@ -338,8 +336,7 @@ You should have received a [copy](LICENSE.html) of the GNU General Public License along with the CodeChat Editor. If not, see [https://www.gnu.org/licenses/](https://www.gnu.org/licenses/). -Notes ------------------------ +

Notes

1. The image used comes from [Monitor icons created by prettycons - Flaticon](https://www.flaticon.com/free-icons/monitor "monitor icons"). diff --git a/server/src/processing/cache-spec.md b/server/src/processing/cache-spec.md index 29ae8b7f..bf49ae0b 100644 --- a/server/src/processing/cache-spec.md +++ b/server/src/processing/cache-spec.md @@ -20,7 +20,7 @@ CodeChat Editor. If not, see Cache spec ========== -The cache stores the location (file name and ID) and contents (inner HTML or +The cache stores the location (file name and ID) and content (inner HTML or code/doc blocks for fragments) of targets and fragments. Targets are HTML elements (excluding ``s and ``s) with an ID. @@ -43,22 +43,67 @@ the two. The cache hydrates data to the Client; the dehydration routes are responsible for removing all cache hydration artifacts. -

Cross references

+

Cross-references

-A `` is a cross reference to a `Target` or a gather -element. The `ref` attribute specifies the destination as an id; the cache then -hydrates the contents based on the location and contents of the target of the -provided destination `id` to e.g. `Inner HTML from target`; this hydrated form -is only present in the Client. +An `optional
content
` is a cross-reference to a +`Target` or a gather element whose id is `ref`. The cache hydrates it to a link +to that target; the link's content is the optional content if provided, or the +target's inner HTML otherwise: `optional
content
`. This hydrated form is +only present in the Client. Since the value of `data-content` is itself +attribute-encoded (see below), its serialized form is encoded twice. Details: -* This element allows no attribute except for `ref`. Since an `` is never - a `Target`, an `id` attribute on it -- including `id="*"` -- would mislead, so - it replaces the contents with an error message. - -* The inner HTML is always taken before cache hydration, to prevent circular +* This element allows no attribute except for `ref`; all other attributes are + silently stripped during hydration. In particular, an `` is never a + `Target`, so an `id` attribute is stripped. While hydration temporarily adds + the `data-content` and `contenteditable` attributes, dehydration removes them. + +* The `` is marked `contenteditable="false"`; the optional content cannot + be edited in the Client. + +* The optional content is the + [permitted content for an ``](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#technical_summary); + this content is cleaned during hydration to + ensure compliance, except as noted below for block-level content in a + paragraph. Cleaning strips `id` and `data-gather` attributes, removes + `` elements, and unwraps nested ``, so the optional content + never defines a target, gather element, cross-reference, auto-assigned `id`, + or fragment. The cleaned content is then hydrated to support math. + + * If the cleaned content, when serialized as HTML, contains at least one + non-[whitespace](https://developer.mozilla.org/en-US/docs/Glossary/Whitespace#in_html) + character, this content becomes the generated link content. This allows + visually empty content (for example, an empty ``), but avoids defining + which HTML nodes count as non-empty. However, TinyMCE removes empty content + (such as an empty ``), which causes constant re-translation messages, + an unfortunate cost for this design simplicity. + + * Otherwise, the inner HTML from the target or gather element is used instead; + for gather elements, the gathered code/doc blocks are not used. +* Note that cleaning can't correct block-level content in a paragraph, since the + HTML parser acts first. For example, `See
text
more.` parses as an `` with no optional + content, followed by a `
` and the text `more.`. + +* The optional content as parsed, but before hydration and cleaning, is always + stored (even when an error is produced) in the `data-content` attribute of the + ``, then restored during dehydration. Dehydration doesn't descend into + the restored content, which was not hydrated when saved. + + * Any previous `data-content` value is overwritten during hydration, then + removed during dehydration. + * If `data-content` is missing during dehydration, the `` optional + content is empty. + * The value for `data-content` is attribute-encoded to avoid removal by + TinyMCE's sanitizer. + * Leading and trailing whitespace may be trimmed: when TinyMCE loads the + content, its XSS attribute sanitizer calls DOMPurify, which trims. The + Server preserves this whitespace. +* When no optional content is provided, the link's content is the target's inner + HTML, which is always taken before cache hydration, to prevent circular dependencies (see also ): ```html @@ -69,45 +114,53 @@ Details: ``` Including cache hydration would cause the inner HTML to be updated each time - the file is processed, outdating the other file. + the file is processed, outdating the other file. Math hydration depends on + nothing in the cache, so the inner HTML is hydrated like optional content each + time it's rendered, both here and in fragment backlinks (see + ). * If the `ref` attribute is missing, the `id` referred to isn't found, refers to - a duplicate id, or is an invalid CSS identifier, the inner text is instead an - appropriate error message. + a duplicate id or a fragment, or is an invalid CSS identifier, the content is + instead an appropriate error message, replacing the displayed optional content + or the target's inner HTML. -* If the cross reference is to a gather element, the text is the gather - element's inner HTML, not the gathered code/doc blocks. + * Cross-references to fragments are not allowed. Without optional content this + would create a circular dependency (see ); + with it, there is none, but a single rule is simpler. -* Cross references to fragments are not allowed; this would create circular - dependencies (see ). +

Implementation of Cross-references

Fragments and gather elements

A gather element such as `

Bazzy things

` is a `Target` with the `data-gather` attribute. It becomes a list -of the contents of fragments it refers to after hydration by the cache. An +of the content of fragments it refers to after hydration by the cache. An example fragment tag, after cache hydration: `See
Bazzy things, Zappy things`. A fragment's -content by default includes the contents of the current doc block and the -contents of the following code/doc block; fragments are not allowed in Markdown -documents (in this case, the fragment contents consist of an error message). -Fragments may include the `following` attribute to enclose a specific number of -the following code/doc blocks; for example, `` includes the current doc block along with the next 3 -code/doc blocks; `following` must be a whole number. +content by default includes the content of the current doc block and the content +of the following code/doc block; fragments are not allowed in Markdown documents +(in this case, the fragment content consists of an error message). Fragments may +include the `following` attribute to enclose a specific number of the following +code/doc blocks; for example, `` +includes the current doc block along with the next 3 code/doc blocks; +`following` must be a whole number. Details: -* Fragment contents may not include a gather element; in this case, the gather - element list of contents will simply include an error message. -* Fragments do support indirection: gather element A includes contents from - fragment B, which contains a cross reference to target C. Changes to target C +* Fragment content may not include a gather element; in this case, the list in + each gather element which includes this fragment shows an error message + instead. +* Fragments do support indirection: gather element A includes content from + fragment B, which contains a cross-reference to target C. Changes to target C make B and A outdated. * If a gather element refers to an `id` that is a `Target`, not a `Fragment`, the resulting output for this in the list of fragments is an error message. * If a gather element refers to an `id` that wasn't found or is a duplicate, its - contents will be replaced by an error message. + content will be replaced by an error message. * Fragments store an HTML rendering of the code and doc blocks they contain, excluding the content produced by hydrating the `` tags, to avoid duplication and circular dependencies. Cross-references in this rendering are @@ -164,21 +217,21 @@ Search (future work) -------------------- The cache will support searching the (cleaned) inner HTML of all `Target`s and -gather elements; search will not include `Fragment` contents. +gather elements; search will not include `Fragment` content. Auto-assignment of ids ---------------------- If `id="*"` on either a fragment, target, or gather element, the cache replaces -this with a random autogenerated `id` placed in the resulting HTML contents, but +this with a random autogenerated `id` placed in the resulting HTML content, but this new `id` is not yet recorded in the cache. It enters the cache only when source containing it is next translated: the Server translates each edit the Client saves back to the Client, to check for changes, which commits the edit; otherwise, the consumer reads the file once it's written to disk. This helps -avoid cases where the cache and file contents become unsynchronized: if the `id` +avoid cases where the cache and file content become unsynchronized: if the `id` is placed in the cache before the write and the write fails, or if the file is never written (it was being scanned, but not actively edited, so the file -contents weren't written back). +content wasn't written back). TODO: an `id="*"` typed in the IDE reaches the source only when the Client sends back the HTML containing its replacement, which it does only once the user edits @@ -207,7 +260,7 @@ lower-numbered layers: 1. `Target::inner_html` (including a gather element's) and `Target::gather_ids` are pure functions of the source (pre-hydration) -- they depend on nothing. -2. `` hydration depends on layer 1 only. +2. `` hydration depends on layer 1 and its optional content only. 3. `Fragment::content` depends on the source plus layer 2. 4. `` backlink hydration depends on layer 1 only: it renders, for each gather element which lists this fragment, that element's containing file, @@ -227,7 +280,7 @@ indirection example, ensuring that propagation terminates. Supporting cross-references, fragments, and gather elements requires the cache to track dependents of an id, so that files containing these dependencies can be -marked `Outdated` (see below); these are sent to the `Cache::consumer_tx` +marked `Outdated` (see below); these are sent to the `Cache::consumer_tx` channel for processing. Dependencies are tracked at file granularity, on the id rather than on the item defining it: `IdEntry::dependents` is the set of files whose rendered output depends on this id, by any means -- an `` @@ -240,9 +293,11 @@ which would trigger outdating dependencies. The state which is checked for differences is: * Target/gather element: type (a target/gather element), path of the containing - file, id, IdState, and inner HTML. + file, id, IdState, and inner HTML. (A cross-reference with optional content + doesn't depend on the target's inner HTML; it is nonetheless outdated when + that HTML changes, for simplicity.) * Fragment: type (a fragment), path of the containing file, id, IdState, and - contents. + content. A gather element's `gather_ids` are absent from this list because no dependent reads them: a cross-reference to a gather element renders only its inner HTML. @@ -269,7 +324,7 @@ outdated file, mark its status as `Outdated` (see ### Gather elements: the reverse edge `dependents` alone is not enough for gather elements, because the reference runs -in both directions: a gather element renders the *contents* of each fragment it +in both directions: a gather element renders the *content* of each fragment it lists, and each of those fragments renders a *backlink* to the gather element (see layer 4 above). The set of gather elements referencing a fragment is therefore not merely bookkeeping -- it is observable output in the fragment's @@ -311,13 +366,25 @@ are reported as errors to the user. All file names (stored as `PathBuf`) must be canonicalized absolute paths. -HTML stored as `Target` inner HTML or in `Fragment` contents requires cleaning: +

HTML cleaning

+ +HTML stored as cross-reference optional content, `Target` inner HTML, or as +`Fragment` content requires cleaning: -* To avoid duplicate IDs, all `id` attributes should be stripped. +* To avoid duplicate IDs, all `id` attributes are stripped. * Note that images, URLs, etc. may not work if the referring path in their new location isn't valid; these simply aren't supported. -* Inner HTML must allow only the +* Cross-reference optional content and `Target` inner HTML must allow only the [permitted content for an `` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#technical_summary). + In particular, it strips ``s and unwraps ``s, replacing them + with cleaned optional content. +* `Fragment` content must preserve the `data-content` attribute of each + ``, since a gather element re-hydrates the `` from it so that its + link leads from the gather element's file. + +
+ Implementation of HTML cleaning +
Cache population and maintenance -------------------------------- @@ -369,8 +436,8 @@ approach means extraneous watcher events from ignored directories, such as The walker is based on the [ignore](https://docs.rs/ignore/latest/ignore/) crate, allowing users to exclude files from the project. After the initial -traverse of the project, it keeps -an [IncrementalIgnore](https://docs.rs/ignore/latest/ignore/struct.IncrementalIgnore.html) +traverse of the project, it keeps an +[IncrementalIgnore](https://docs.rs/ignore/latest/ignore/struct.IncrementalIgnore.html) for checking files in the `WatcherPathState`s received from the watcher. * If the path is a deleted file or directory and is not ignored by the walker, @@ -405,7 +472,7 @@ closed or the weak reference can't be upgraded. It is implemented as a thread. The consumer decides whether a file changed by its stamp, as Git's index does: a snapshot of the file's length and modification time (plus its change time and -inode on Unix), taken before its contents were read. A stamp taken within a few +inode on Unix), taken before its content was read. A stamp taken within a few seconds of the file's last write never matches, since a later write in the same timestamp tick could leave this metadata unchanged (Git's "racy clean" problem). diff --git a/server/src/processing/cache.rs b/server/src/processing/cache.rs index d0b6fce8..5af223a6 100644 --- a/server/src/processing/cache.rs +++ b/server/src/processing/cache.rs @@ -258,7 +258,7 @@ pub(super) struct Target { pub(super) _line: usize, } -/// This defines a cross reference to a `Target`. +/// This defines a cross reference to a `Target` or a gather element. pub(super) struct Xref { /// The id cross-referenced. pub(super) id: String, From 225d627739f5a5f5d555bd68403810e48424fb75 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Thu, 5 Nov 2026 19:11:45 -0600 Subject: [PATCH 04/29] Add: optional content in cross-references. Implement the cross-reference spec from the previous commit: an may hold optional content, which becomes the text of its link in place of the target's inner HTML. Hydration saves this content in an attribute-encoded data-content attribute, from which dehydration restores it and a gather element re-hydrates its link. Hydration now strips every attribute but ref, rather than reporting an id as an error. Both optional content and a target's inner HTML are cleaned to the permitted content of an
, then hydrated so that their math renders. Co-Authored-By: Claude Opus 5.5 --- Cargo.lock | 3 + server/Cargo.toml | 2 +- server/src/ide/vscode/tests.rs | 10 +- server/src/processing.rs | 410 ++++++++++++++++++++---------- server/src/processing/tests.rs | 322 ++++++++++++++++++++--- server/src/translation.rs | 32 ++- server/tests/overall/overall_5.rs | 126 +++++++++ 7 files changed, 735 insertions(+), 170 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9e57637e..a0abe314 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1564,6 +1564,9 @@ checksum = "2e815d50d9e411ba2690d730e6ec139c08260dddb756df315dbd16d01a587226" dependencies = [ "memchr", "pastey 0.1.1", + "phf 0.13.1", + "phf_codegen 0.13.1", + "serde_json", ] [[package]] diff --git a/server/Cargo.toml b/server/Cargo.toml index cab06685..60b2be97 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -57,7 +57,7 @@ futures-util = "0.3.29" htmd = { git = "https://github.com/bjones1/htmd.git", branch = "dom-interface", version = "0.5" } # This must match the version of `markup5ever_rcdom`. html5ever = "0.39" -htmlize = "1.0.6" +htmlize = { version = "1.0.6", features = ["unescape"] } ignore = "0.4" imara-diff = { version = "0.2", features = [] } indoc = "2.0.5" diff --git a/server/src/ide/vscode/tests.rs b/server/src/ide/vscode/tests.rs index 9c6fe661..7bbf3883 100644 --- a/server/src/ide/vscode/tests.rs +++ b/server/src/ide/vscode/tests.rs @@ -1552,7 +1552,7 @@ async fn test_vscode_ide_websocket10() { to: 1, indent: String::new(), delimiter: "#".to_string(), - contents: r#"

See id "foo" not found."#.to_string(), + contents: r#"

See id "foo" not found."#.to_string(), }], }), version: 0.0, @@ -1615,8 +1615,8 @@ async fn test_vscode_ide_websocket10() { delimiter: None, contents: vec![StringDiff { from: 0, - to: Some(97), - insert: "

See Foo.".to_string(), + to: Some(110), + insert: "

See Foo.".to_string(), }], } )], @@ -1854,7 +1854,7 @@ async fn test_vscode_ide_websocket11() { EditorMessage { id: INITIAL_MESSAGE_ID + 4.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::UpdateToc( - "

" + "" .to_string() ), } @@ -1897,7 +1897,7 @@ async fn test_vscode_ide_websocket11() { EditorMessage { id: INITIAL_MESSAGE_ID + 6.0 * MESSAGE_ID_INCREMENT, message: EditorMessageContents::UpdateToc( - "" + "" .to_string() ), } diff --git a/server/src/processing.rs b/server/src/processing.rs index 0edbcefc..9436d001 100644 --- a/server/src/processing.rs +++ b/server/src/processing.rs @@ -490,7 +490,7 @@ pub fn codechat_for_web_to_source( let html_to_markdown = new_html_to_markdown(); let converter = HtmlToMarkdownWrapped::new(&html_to_markdown); let tree = html_to_dom(&code_mirror.doc, None)?; - dehydrating_walk_node(&tree); + dehydrating_walk_node(&tree)?; return converter .convert(&tree) .map_err(CodechatForWebToSourceError::HtmlToMarkdownFailed); @@ -704,7 +704,7 @@ pub fn doc_block_html_to_markdown( if let CodeDocBlock::DocBlock(doc_block) = code_doc_block { last_doc_block_index = Some(index); let tree = html_to_dom(&doc_block.contents, dom_location)?; - dehydrating_walk_node(&tree); + dehydrating_walk_node(&tree)?; // Calculate the total delimiter width: the delimiter width plus the // extra space after it. Special case: an empty delimiter means @@ -1212,7 +1212,7 @@ static AMMONIA_OPTIONS: LazyLock = LazyLock::new(|| { "iframe", &["width", "height", "src", "allowfullscreen", "frameborder"], ) - .add_tag_attributes("xref", &["contenteditable", "ref"]) + .add_tag_attributes("xref", &["contenteditable", "data-content", "ref"]) .add_tag_attributes("fragment", &["contenteditable", "id", "following"]) // Keep HTML comments, which Ammonia strips by default. .strip_comments(false) @@ -1220,44 +1220,58 @@ static AMMONIA_OPTIONS: LazyLock = LazyLock::new(|| { // manually and it should not be stripped without some extra work (perhaps // adding custom attributes?). .link_rel(None); + allow_phrasing_attributes(&mut b); b }); -// Clean HTML for storage as a `Target`'s inner HTML, per the spec in -// `cache.rs`: only the +// Clean HTML which becomes the content of a hydrated link -- a `Target`'s inner +// HTML, or a cross-reference's optional content -- per +// : only the // [permitted content for an `` element](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/a#technical_summary) -// is allowed (phrasing content, excluding interactive content), since this HTML -// becomes the text of a hydrated cross-reference link. Disallowed tags are -// stripped but their text is kept; `id` attributes are stripped because they -// aren't in the allowlist, preventing duplicate ids when the HTML is rendered -// in a referencing file. -static CLEAN_TARGET_HTML: LazyLock = LazyLock::new(|| { +// is allowed. This is a conservative subset of phrasing content which excludes +// interactive content, along with media and other elements not useful in link +// text. It also includes `` and ``, which aren't phrasing content but +// are needed by ``; Ammonia can't limit them to that parent, so a stray +// one remains. Most disallowed tags are stripped but their content is kept, +// which unwraps a nested `` to its own optional content. A ``, +// `-->?>]]> ``````````````````````` @@ -1568,11 +1573,10 @@ fn get_dom_root( /// block separately. Text before the first separator isn't a doc block. /// /// Markdown conversion may still hide the separators of later doc blocks: a -/// fenced code block opened by a fence longer than the separator's stays open, -/// while ``, exposing that -/// separator's fences. Report this here, since hydration would otherwise commit -/// the facts of the remaining doc blocks to the cache, dropping any targets the -/// hidden doc blocks contain. +/// fenced code block opened by a fence longer than the separator's stays open. +/// Report this here, since hydration would otherwise commit the facts of the +/// remaining doc blocks to the cache, dropping any targets the hidden doc +/// blocks contain. fn doc_blocks_to_dom( // The HTML of all doc blocks, with fences removed and each preceded by its // separator. @@ -1587,7 +1591,7 @@ fn doc_blocks_to_dom( .collect(); if doc_block_bounds.len() != doc_block_count { return Err(io::Error::other( - "because an unclosed code block or declaration hides later doc blocks", + "because an unclosed code block hides later doc blocks", )); } doc_block_bounds.push(html.len()); diff --git a/server/src/processing/tests.rs b/server/src/processing/tests.rs index 7950c18e..7d1ab71d 100644 --- a/server/src/processing/tests.rs +++ b/server/src/processing/tests.rs @@ -2131,29 +2131,35 @@ fn test_hydrate_target_inner_html_math() { ); } -// Verify that a tag or comment left open in a doc block closes where that doc -// block ends, leaving the code and the later doc block intact, both when -// translated and after a save. +// Verify that a tag, comment, or declaration left open in a doc block closes +// where that doc block ends, leaving the code and the later doc block intact, +// both when translated and after a save, which closes a declaration as a +// comment. Translating and saving the saved text must change nothing. #[test] fn test_hydrate_unclosed_tag() { + let translate = |source: &str| { + source_to_codechat_for_web(source, Path::new("foo.js"), 0.0, false, None).unwrap() + }; for (unclosed_tag, saved_doc_block) in [ ("", "// "), ("See ", "// See "), ("", "// "), (""), + (""), ("", "//
"), ] { - let translation = source_to_codechat_for_web( - &format!("// {unclosed_tag}\nlet a = 1;\n// Next.\nlet b = 2;\n"), - Path::new("foo.js"), - 0.0, - false, - None, - ) - .unwrap(); + let translation = translate(&format!( + "// {unclosed_tag}\nlet a = 1;\n// Next.\nlet b = 2;\n" + )); + let saved = format!("{saved_doc_block}\nlet a = 1;\n// Next.\nlet b = 2;\n"); assert_eq!( codechat_for_web_to_source(&translation).unwrap(), - format!("{saved_doc_block}\nlet a = 1;\n// Next.\nlet b = 2;\n"), + saved, + "{unclosed_tag}" + ); + assert_eq!( + codechat_for_web_to_source(&translate(&saved)).unwrap(), + saved, "{unclosed_tag}" ); let CodeMirrorDiffable::Plain(code_mirror) = translation.source else { @@ -2430,25 +2436,17 @@ fn test_hydrate_unclosed_xref_later_target() { // Verify that Markdown which hides the separators of later doc blocks produces // an error, not a panic or empty doc blocks, which the next save would write to // the source. The separator's closing fence is 23 characters long, so it can't -// close the first of these. The others end an HTML block at the separator's -// first `>`, exposing a fence which hides the next separator. In the last of -// these, a later separator's fence closes it, leaving that separator visible. +// close this one. #[test] fn test_hydrate_hidden_separator() { let long_fence = "`".repeat(24); - for source in [ - format!("// {long_fence}\nlet a = 1;\n// Next.\nlet b = 2;\n"), - "// Date: Sat, 7 Nov 2026 22:32:45 -0600 Subject: [PATCH 16/29] Perf: parse a cross-reference's content fewer times. hydrate_link_content now returns nodes instead of a string, so a link's content is no longer serialized and parsed again, and blank optional content isn't hydrated at all. A cross-reference without optional content drops from five html5ever parses to two, all while the project's cache lock is held. Co-Authored-By: Claude Opus 5.5 --- server/src/processing.rs | 66 ++++++++++++++++++++++------------ server/src/processing/tests.rs | 2 ++ 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/server/src/processing.rs b/server/src/processing.rs index f3babd79..6c02415d 100644 --- a/server/src/processing.rs +++ b/server/src/processing.rs @@ -1982,20 +1982,19 @@ fn xref_content( } => { let href = format!("{}#{id}", relative_url(path, target_path)); // The link's content is the hydrated optional content, unless that - // is blank once serialized; then it's the target's hydrated inner - // HTML. ASCII whitespace is exactly what HTML considers whitespace. - let hydrated_content = - hydrate_link_content(&optional_content(node).unwrap_or_default())?; - let content = if hydrated_content.trim_ascii().is_empty() { - hydrate_link_content(&target.inner_html)? + // is blank; then it's the target's hydrated inner HTML. Blank + // optional content hydrates to blank content, so it isn't hydrated. + // ASCII whitespace is exactly what HTML considers whitespace. + let optional_content = optional_content(node).unwrap_or_default(); + let mut content = if optional_content.trim_ascii().is_empty() { + vec![] } else { - hydrated_content + hydrate_link_content(&optional_content)? }; - vec![new_element( - "a", - vec![("href", href)], - parse_html_fragment(&content)?, - )] + if is_blank(&content) { + content = hydrate_link_content(&target.inner_html)?; + } + vec![new_element("a", vec![("href", href)], content)] } IdResolution::Fragment { .. } => vec![error_span(&format!( "id \"{id}\" names a fragment; a cross-reference must name a target or gather element" @@ -2016,15 +2015,31 @@ fn xref_content( /// class, so without it the Client's copy of this link never matches a /// re-translation (see `compare_html` in `translation.rs`), sending the Client /// a re-translation after each save. A target's inner HTML is stored before -/// hydration, so this runs each time it's rendered. +/// hydration, so this runs each time it's rendered, while the caller holds the +/// project's cache lock. fn hydrate_link_content( // The optional content as parsed, or a target's stored inner HTML. content: &str, - // The link's content. -) -> io::Result { + // The detached nodes of the link's content. +) -> io::Result>> { let dom = html_to_dom(&CLEAN_LINK_CONTENT_HTML.clean(content).to_string(), None)?; hydrate_descendants(&dom); - dom_to_html(&dom) + Ok(take_dom_nodes(&dom)) +} + +/// Report whether a link's content is blank, which +/// defines as serializing to nothing but +/// whitespace. Any node other than a text node serializes to markup, which +/// isn't whitespace. +fn is_blank( + // The link's content. + nodes: &[Rc], + // True if this content is blank. +) -> bool { + nodes.iter().all(|node| match &node.data { + NodeData::Text { contents } => contents.borrow().trim_ascii().is_empty(), + _ => false, + }) } /// The content of one hydrated ``: a backlink to each gather element @@ -2052,7 +2067,7 @@ fn fragment_backlinks( children.push(new_element( "a", vec![("href", href)], - parse_html_fragment(&hydrate_link_content(&backlink.target.inner_html)?)?, + hydrate_link_content(&backlink.target.inner_html)?, )); } Ok(children) @@ -2435,14 +2450,21 @@ fn set_element_children(node: &Rc, children: Vec>) { /// Parse an HTML string into a list of detached nodes, ready to insert into /// another DOM. fn parse_html_fragment(html: &str) -> io::Result>> { - let dom = html_to_dom(html, None)?; - let root = get_dom_root(&dom); - let children: Vec> = root.children.borrow().clone(); - root.children.borrow_mut().clear(); + Ok(take_dom_nodes(&html_to_dom(html, None)?)) +} + +/// Remove the top-level nodes from a DOM, detaching them so that they're ready +/// to insert into another DOM; this is the inverse of `nodes_to_dom`. +fn take_dom_nodes( + // A DOM returned by `html_to_dom`. + dom: &Rc, + // The detached nodes. +) -> Vec> { + let children = get_dom_root(dom).children.take(); for child in &children { child.parent.set(None); } - Ok(children) + children } /// Build a DOM from detached nodes, such as `parse_html_fragment` returns. diff --git a/server/src/processing/tests.rs b/server/src/processing/tests.rs index 7d1ab71d..a9f1e37c 100644 --- a/server/src/processing/tests.rs +++ b/server/src/processing/tests.rs @@ -2046,6 +2046,7 @@ fn test_hydrate_xref_optional_content() { // * Hidden // * // * + // * // * Missing "# ), @@ -2071,6 +2072,7 @@ fn test_hydrate_xref_optional_content() { "
  • Title", "
  • ", "
  • Title", + "
  • Title", "
  • id \"nope\" not found", "" ) From 567684dd987b13d957acf9ea73e0c2f695df62a8 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Sun, 8 Nov 2026 09:26:23 -0600 Subject: [PATCH 17/29] Clean: improve comment, wrap lines. --- client/src/CodeMirror-integration.mts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/src/CodeMirror-integration.mts b/client/src/CodeMirror-integration.mts index 093579c4..778aaa0f 100644 --- a/client/src/CodeMirror-integration.mts +++ b/client/src/CodeMirror-integration.mts @@ -163,7 +163,7 @@ const CODECHAT_DOC_HIDDEN = "CodeChat-doc-hidden"; // [StateField](https://codemirror.net/docs/ref/#state.StateField^define): the // state required to store all doc blocks. Conveniently, a // [DecorationSet](https://codemirror.net/docs/ref/#view.DecorationSet) is a -// [RangeSet](https://codemirror.net/docs/ref/#state.RangeSet)<[Decoration](https://codemirror.net/docs/ref/#view.Decoration)\>, +// [RangeSet](https://codemirror.net/docs/ref/#state.RangeSet)\<[Decoration](https://codemirror.net/docs/ref/#view.Decoration)\>, // each element of which contains the required range and the needed HTML in the // Decoration -- all the required state. Making it a DecorationSet provides an // easy way to store all doc blocks. @@ -869,10 +869,10 @@ const linkOutsideTinymce = ( // `tinymce.util.VK.metaKeyPressed` accepts the click (see `Following links` in // [tinymce-config.mts](tinymce-config.mts)), so `isFollowClick` repeats that // test: TinyMCE loads only once a doc block gains the focus, too late for a -// click which arrives first. On macOS and iOS, which TinyMCE recognizes from the -// user agent much as below, the test requires Cmd; elsewhere, it requires Ctrl -// without Alt, since AltGr, which types characters on many Windows keyboard -// layouts, reports both. +// click which arrives first. On macOS and iOS, which TinyMCE recognizes from +// the user agent much as below, the test requires Cmd; elsewhere, it requires +// Ctrl without Alt, since AltGr, which types characters on many Windows +// keyboard layouts, reports both. const isMacOsOrIos = /iphone|ipad|mac os x/.test( navigator.userAgent.toLowerCase(), ); @@ -1792,6 +1792,8 @@ export const codeMirrorLoad = async ( break; default: + // Load an arbitrary parser, since `parser` is required when + // creating the editor. parser = ( await import("@codemirror/lang-javascript") ).javascript(); From b6b3c9c8c61c0d8cdf75b693c62f42f3614314e3 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 14:44:09 -0600 Subject: [PATCH 18/29] Fix: make the Client read-only while the IDE's text can't be translated. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 2 +- client/src/CodeChatEditor.mts | 38 ++++++++++++++++++++- client/src/CodeChatEditorFramework.mts | 15 +++++++++ client/src/CodeMirror-integration.mts | 44 +++++++++++++++++++----- server/src/translation.rs | 15 +++++---- server/tests/overall/overall_5.rs | 46 +++++++++++++++++++++++--- 6 files changed, 138 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e52efbe4..ce1f7025 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,7 @@ Changelog * Report an error instead of crashing when an unclosed code block hides later doc blocks, and instead of erasing text when an unclosed tag hides the text after it. The Client shows this error in a toast and keeps showing the last - text which translated, ignoring edits made there until the error is fixed. + text which translated, read-only until the error is fixed. * Keep anything inside a ``, such as the text after a missing ``, instead of erasing it on the next save. * Fix retranslations of math in gather elements. diff --git a/client/src/CodeChatEditor.mts b/client/src/CodeChatEditor.mts index aa25cdf7..6acdca48 100644 --- a/client/src/CodeChatEditor.mts +++ b/client/src/CodeChatEditor.mts @@ -58,6 +58,7 @@ import { mathJaxUnTypeset, scrollToLine as codemirrorScrollToLine, setCodeMirrorPositions, + setCodeMirrorReadOnly, } from "./CodeMirror-integration.mjs"; import "./graphviz-webcomponent-setup.mjs"; // This must be imported *after* the previous setup import, so it's placed here, @@ -127,6 +128,7 @@ declare global { scrollLine?: number, ) => void; showToast: (text: string) => void; + setReadOnly: (readOnly: boolean) => void; allow_navigation: boolean; }; CodeChatEditor_test: unknown; @@ -163,13 +165,40 @@ export const setIsDirty = (value: boolean = true) => { export const getIsDirty = () => isDirty; +// True while the IDE holds text which the Server can't translate. The Client +// still shows the last text which translated, and the Server rejects edits to +// it, since they would replace the IDE's newer text (see `client_update` in +// [translation.rs](../../server/src/translation.rs)). So, the Client is +// read-only until the IDE's text translates. +let isReadOnly = false; + +export const getIsReadOnly = () => isReadOnly; + +// Make the Client read-only or editable. The read-only modes of CodeMirror and +// TinyMCE keep the cursor, so the user can still select, copy, and follow +// links. +const setReadOnly = ( + // True to make the Client read-only. + readOnly: boolean, +) => { + isReadOnly = readOnly; + setTinymceMode(); + setCodeMirrorReadOnly(readOnly); +}; + +const setTinymceMode = () => + tinymceInstance()?.mode.set(isReadOnly ? "readonly" : "design"); + // ### TinyMCE dynamic import // // TinyMCE is dynamically imported when `init` is called. export const init = async (options: RawEditorOptions) => { const tinymceConfig = await import("./tinymce-config.mjs"); tinymce = tinymceConfig.tinymce; - return await tinymceConfig.init(options); + const editors = await tinymceConfig.init(options); + // The Client may have become read-only while TinyMCE loaded. + setTinymceMode(); + return editors; }; // The imported module is stored in this variable. export let tinymce: undefined | TinyMCE = undefined; @@ -271,6 +300,12 @@ const _openLp = async ( consoleLog(`Ignoring re-translation because Client is dirty.`); return; } + // The Server sends an update which isn't a re-translation only when the + // IDE's text translates, ending the read-only state which began when the + // Framework received a `CannotTranslateSource` error. + if (!isReTranslation) { + setReadOnly(false); + } try { // Use @@ -809,6 +844,7 @@ onDomContentLoaded(async () => { sendUpdate, scrollToLine, showToast, + setReadOnly, allow_navigation: false, }; }); diff --git a/client/src/CodeChatEditorFramework.mts b/client/src/CodeChatEditorFramework.mts index 040bd09f..de0b0fae 100644 --- a/client/src/CodeChatEditorFramework.mts +++ b/client/src/CodeChatEditorFramework.mts @@ -338,6 +338,21 @@ class WebSocketComm { `Error in message ${id}: ${JSON.stringify(resultContents.Err)}.`, resultContents.Err, ); + // The Server sends this error when the IDE's text first + // fails to translate (see `ide_update` in + // [translation.rs](../../server/src/translation.rs)). + // Queue this behind any update still being applied: + // that update holds older text, so applying it would + // otherwise end the read-only state. + const err = resultContents.Err; + if ( + typeof err === "object" && + "CannotTranslateSource" in err + ) { + this.promise = this.promise.finally(() => + getClient()?.setReadOnly(true), + ); + } } break; } diff --git a/client/src/CodeMirror-integration.mts b/client/src/CodeMirror-integration.mts index 778aaa0f..d44628ba 100644 --- a/client/src/CodeMirror-integration.mts +++ b/client/src/CodeMirror-integration.mts @@ -63,6 +63,7 @@ import { } from "@codemirror/view"; import { ChangeDesc, + Compartment, EditorState, Extension, Prec, @@ -79,6 +80,7 @@ import type { Editor, EditorEvent, Events } from "tinymce"; // ### Local import { + getIsReadOnly, setIsDirty, startAutoUpdateTimer, saveSelection, @@ -150,6 +152,9 @@ const exceptionSink = EditorView.exceptionSink.of((exception) => { const TINYMCE_INST = "TinyMCE-inst"; const CODECHAT_DOC_HIDDEN = "CodeChat-doc-hidden"; +// Holds the `readOnly` facet, so that `setCodeMirrorReadOnly` can change it. +const readOnlyCompartment = new Compartment(); + // Doc blocks in CodeMirror // ------------------------ // @@ -706,16 +711,22 @@ const getContents = (element: Element): [HTMLDivElement, boolean] => { }; // Allow only spaces and delete/backspaces when editing the indent of a doc -// block. This is registered (see `DocBlockPlugin`'s `focusin` handler below) as -// a `beforeinput` listener on a doc block's indent div. It's defined here, as a -// single stable function reference, rather than as an inline arrow function -// created inside the `focusin` handler: `addEventListener` only skips re-adding -// a listener that's reference-equal to one already registered on the same -// target, and `focusin` can fire repeatedly on the same (unchanged, and -// therefore DOM-preserving -- see `DocBlockWidget.eq`) indent div, e.g. by -// blurring then refocusing it. A fresh arrow function per `focusin` call would -// defeat that dedup and accumulate listeners. +// block, and nothing in a read-only Client, since neither CodeMirror nor +// TinyMCE manages the indent. This is registered (see `DocBlockPlugin`'s +// `focusin` handler below) as a `beforeinput` listener on a doc block's indent +// div. It's defined here, as a single stable function reference, rather than +// as an inline arrow function created inside the `focusin` handler: +// `addEventListener` only skips re-adding a listener that's reference-equal to +// one already registered on the same target, and `focusin` can fire repeatedly +// on the same (unchanged, and therefore DOM-preserving -- see +// `DocBlockWidget.eq`) indent div, e.g. by blurring then refocusing it. A fresh +// arrow function per `focusin` call would defeat that dedup and accumulate +// listeners. const onIndentBeforeinput = (event: InputEvent) => { + if (getIsReadOnly()) { + event.preventDefault(); + return; + } // Only modify the behavior of inserts. if (event.data) { // Block any insert that's not an insert of spaces. TODO: need to @@ -1826,6 +1837,9 @@ export const codeMirrorLoad = async ( }), exceptionSink, autosaveExtension, + readOnlyCompartment.of( + EditorState.readOnly.of(getIsReadOnly()), + ), // Make tab an indent per the // [docs](https://codemirror.net/examples/tab/). TODO: // document a way to escape the tab key per the same docs. @@ -1980,6 +1994,18 @@ export const scrollToLine = ( } }; +// Make the code blocks read-only or editable. CodeMirror then ignores input and +// disables its editing commands, but still moves the cursor. +export const setCodeMirrorReadOnly = ( + // True to make the code blocks read-only. + readOnly: boolean, +) => + currentView?.dispatch({ + effects: readOnlyCompartment.reconfigure( + EditorState.readOnly.of(readOnly), + ), + }); + // Apply a `StringDiff` to the before string to produce the after string. export const applyDiffStr = (before: string, diffs: StringDiff[]) => { // Walk from the last diff to the first. JavaScript doesn't have reverse diff --git a/server/src/translation.rs b/server/src/translation.rs index d2d587ef..00baf59f 100644 --- a/server/src/translation.rs +++ b/server/src/translation.rs @@ -302,8 +302,7 @@ struct TranslationTask { sent_full: bool, /// The error from translating the IDE's latest text, if that failed. Until /// the IDE sends text which translates, the Client keeps showing the last - /// text which did, and can't edit the IDE's newer text; see - /// `client_update`. + /// text which did, read-only; see `client_update`. ide_translation_error: Option, /// Most recent capture metadata supplied by the IDE. Server-generated /// capture events reuse this so translated write events retain the same @@ -978,8 +977,10 @@ impl TranslationTask { // // Report this only to the Client, whose // text is now out of date, and which shows - // any error result as a toast (see `case - // "Result"` in + // any error result as a toast. On this + // error, the Client also becomes read-only + // until it receives an update which isn't a + // re-translation (see `case "Result"` in // `CodeChatEditorFramework.mts`). Report it // only when it first appears, since the IDE // sends an update on each pause in typing, @@ -1257,8 +1258,10 @@ impl TranslationTask { }; // The Client's text is older than the IDE's when the IDE's can't be // translated. Forwarding this edit would replace the IDE's newer text - // with the Client's, so reject the edit instead. The Client then holds - // text this struct doesn't, so it needs the full text next. + // with the Client's, so reject the edit instead. The Client becomes + // read-only once it learns of the error, so this rejects only an edit + // it sent before then. The Client then holds text this struct doesn't, + // so it needs the full text next. if update_message_contents.contents.is_some() && let Some(err) = &self.ide_translation_error { diff --git a/server/tests/overall/overall_5.rs b/server/tests/overall/overall_5.rs index 3c114c83..a2a15a4e 100644 --- a/server/tests/overall/overall_5.rs +++ b/server/tests/overall/overall_5.rs @@ -971,7 +971,7 @@ make_test!( // When the IDE sends source which can't be translated, the Client shows one // toast, however many such updates arrive, and keeps showing the last source -// which could be translated. See `ide_update` in +// which could be translated, read-only. See `ide_update` in // [translation.rs](../../src/translation.rs). async fn test_untranslatable_source_toast_core( // The Server, through which the test plays the IDE. @@ -1036,13 +1036,32 @@ async fn test_untranslatable_source_toast_core( toast_text.contains("unknown lexer nope"), "Unexpected toast: {toast_text}" ); - // Give a second toast time to appear, if the Server sent one. - sleep(SETTLE_TIME).await; + + // Typing in a code block, then in a doc block, changes neither. The only + // line of code is the blank line which follows the doc block. + let code_line_css = By::Css(".cm-line"); + let code_line = driver.query(code_line_css.clone()).first().await?; + code_line.click().await?; + code_line.send_keys("y").await?; + let doc_block = driver.query(By::Css(".CodeChat-doc")).first().await?; + click_element_top_left(&driver, &doc_block).await?; + // Find TinyMCE once the click moves it into the doc block. + let tinymce_contents = driver.query(By::Id("TinyMCE-inst")).first().await?; + tinymce_contents.wait_until().clickable().await?; + tinymce_contents.send_keys("z").await?; + // Only the cursor moves. This also gives a second toast time to appear, as + // it would if the Client sent an edit, which the Server rejects. + let mut client_id = INITIAL_CLIENT_MESSAGE_ID; + assert_eq!( + next_unhandled_message(&codechat_server, &mut client_id, SETTLE_TIME).await, + None + ); assert_eq!( driver.find_all(By::Css(".toastify")).await.unwrap().len(), 1 ); - + let code_line_text = driver.query(code_line_css).first().await?.text().await?; + assert_eq!(code_line_text, ""); let doc_block_css = By::Css(".CodeChat-doc-contents"); let doc_block_text = driver .query(doc_block_css.clone()) @@ -1052,7 +1071,8 @@ async fn test_untranslatable_source_toast_core( .await?; assert_eq!(doc_block_text, "Before."); - // Once the source can be translated, the Client shows it. + // Once the source can be translated, the Client shows it, and its edits + // reach the IDE again. let ide_id = codechat_server .send_message_update_plain(path_str, Some(("# After.\n".to_string(), 3.0)), None, None) .await @@ -1066,6 +1086,22 @@ async fn test_untranslatable_source_toast_core( ); let doc_block_text = driver.query(doc_block_css).first().await?.text().await?; assert_eq!(doc_block_text, "After."); + tinymce_contents.send_keys("x").await?; + let msg = next_unhandled_message(&codechat_server, &mut client_id, TIMEOUT) + .await + .unwrap(); + assert_eq!(msg.id, client_id); + assert!( + matches!( + &msg.message, + EditorMessageContents::Update(UpdateMessageContents { + contents: Some(_), + .. + }) + ), + "Expected an edit: {msg:#?}" + ); + codechat_server.send_result(client_id, None).await.unwrap(); assert_no_more_messages(&codechat_server).await; From 74dbd466fca073616f9f3f7fb697a78980b4d32e Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 14:44:49 -0600 Subject: [PATCH 19/29] Fix: update dependencies with security advisories. --- Cargo.lock | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a0abe314..53c5a374 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,9 +21,9 @@ dependencies = [ [[package]] name = "actix-files" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4eb203ca8ec2fd8261d7ab0b46b0d33ac80abfc780bfdd021009decc61df62f" +checksum = "c6f3a6769c3bc1c7d8e04b5c15f0c87489924c93455d9820296c219475a9051a" dependencies = [ "actix-http", "actix-service", @@ -45,16 +45,17 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.20.0" +version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d20a22850ea7fecad12c5f8cd97d246c3af1f04ef400033977c2f13425c45816" +checksum = "3422032be73eeb15bafdb64086386385875b653eb418a80241d1f98473e86ea6" dependencies = [ "actix-codec", "actix-service", "actix-utils", - "base64 0.22.1", + "base64 0.23.1", "bitflags", "brotli", + "brotli-decompressor", "bytes", "bytestring", "derive_more", @@ -156,9 +157,9 @@ dependencies = [ [[package]] name = "actix-web" -version = "4.18.1" +version = "4.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f8da0d2ae4200dde8773d72ba47a65c220b251ba7b9248db5bd263c247e959" +checksum = "acd6966acfcc7b66b37bdeea7d11665d5accac89333767e1784d2cecd33984e7" dependencies = [ "actix-codec", "actix-http", From 2d66f4f125b118eaa1f2eaa2713c14b19f8f597d Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 15:16:34 -0600 Subject: [PATCH 20/29] Clean: remove outdated comment. --- client/src/tinymce-config.mts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/client/src/tinymce-config.mts b/client/src/tinymce-config.mts index de71df9c..a68cbd84 100644 --- a/client/src/tinymce-config.mts +++ b/client/src/tinymce-config.mts @@ -103,12 +103,6 @@ export const init = async ( // [docs](https://www.tiny.cloud/docs/configure/editor-appearance/#fixed_toolbar_container). fixed_toolbar_container: "#CodeChat-menu", inline: true, - // When true, this still prevents hyperlinks to anchors on the - // current page from working correctly. There's an onClick handler - // that prevents links in the current page from working -- need to - // look into this. See also - // [a related GitHub issue](https://github.com/tinymce/tinymce/issues/3836). - //readonly: true // Per the comment above, this is commented out. // Use relative URLs in hyperlinks. relative_urls: true, // Disable the From 31cb4c9adb2b3516cbfaec41209381e55cd89c2d Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 15:48:48 -0600 Subject: [PATCH 21/29] Test: run the VSCode tests' webserver on an OS-assigned port. The shared test webserver bound to fixed port 8080, colliding with anything else holding that port, then polled `/ping` until it started. It now binds to port 0 and reads back the assigned port; since the port is bound before the tests connect, they no longer wait for startup. The test server therefore no longer registers `LifecycleRoutes`, and the `webserver` tests no longer borrow the VSCode tests' port constant. Co-Authored-By: Claude Opus 5.5 --- server/src/ide/vscode/tests.rs | 135 ++++++++++++++++++--------------- server/src/webserver.rs | 3 +- server/src/webserver/tests.rs | 9 +-- 3 files changed, 78 insertions(+), 69 deletions(-) diff --git a/server/src/ide/vscode/tests.rs b/server/src/ide/vscode/tests.rs index 5e06d782..5cf34a20 100644 --- a/server/src/ide/vscode/tests.rs +++ b/server/src/ide/vscode/tests.rs @@ -21,12 +21,12 @@ use std::{ env, fs::{self, File}, - io::{Error, Read}, + io::Read, net::SocketAddr, path::{self, Path, PathBuf}, sync::LazyLock, - thread::{self, JoinHandle}, - time::{Duration, SystemTime}, + thread, + time::Duration, }; use assert_fs::TempDir; @@ -54,7 +54,7 @@ use crate::webserver::{ use crate::{ ide::vscode::VscodeRoutes, translation::{EolType, find_eol_type}, - webserver::{LifecycleRoutes, main, test_root_path}, + webserver::{init_server, setup_server, test_root_path}, }; use crate::{ processing::{ @@ -71,26 +71,29 @@ use test_utils::{ // Globals // ------- // -// Run a single webserver for all tests. -static WEBSERVER_HANDLE: LazyLock>> = LazyLock::new(|| { +// Start a webserver shared by all tests in this process; this is the port it +// listens on. Bind to an OS-assigned port, so these tests don't collide with +// anything else holding a fixed port (a running CodeChat Editor, or another +// test process under `cargo nextest`). The port is bound before this returns, +// so the OS queues connections until the server begins accepting them; tests +// needn't wait for it to start. +static IP_PORT: LazyLock = LazyLock::new(|| { + init_server(&test_root_path(), log::LevelFilter::Debug).unwrap(); + let (server, app_state) = setup_server( + // A port of 0 requests the OS to assign an open port. + &SocketAddr::new("127.0.0.1".parse().unwrap(), 0), + None, + VscodeRoutes, + ) + .expect("Unable to start the test webserver."); thread::spawn(|| { - main( - &test_root_path(), - &SocketAddr::new("127.0.0.1".parse().unwrap(), IP_PORT), - None, - log::LevelFilter::Debug, - (VscodeRoutes, LifecycleRoutes), - ) - }) + actix_web::rt::System::new() + .block_on(server) + .expect("The test webserver failed."); + }); + *app_state.port.lock().unwrap() }); -// Constants -// --------- -/// The default port on which the server listens for incoming connections. -pub const IP_PORT: u16 = 8080; -/// Allow slower CI runners enough time to start the shared test webserver. -const WEBSERVER_START_TIMEOUT: Duration = Duration::from_secs(6); - // Support functions // ----------------- /// Send a message via a websocket. @@ -138,10 +141,13 @@ async fn read_message( type WebSocketStreamTcp = WebSocketStream>; async fn connect_async_server(prefix: &str, connection_id: &str) -> WebSocketStreamTcp { - connect_async(format!("ws://127.0.0.1:{IP_PORT}{prefix}/{connection_id}")) - .await - .expect("Failed to connect") - .0 + connect_async(format!( + "ws://127.0.0.1:{}{prefix}/{connection_id}", + *IP_PORT + )) + .await + .expect("Failed to connect") + .0 } async fn connect_async_ide(connection_id: &str) -> WebSocketStreamTcp { @@ -208,22 +214,6 @@ async fn prep_test_core( ) -> (TempDir, PathBuf, WebSocketStreamTcp, WebSocketStreamTcp) { configure_testing_logger(); let (temp_dir, test_dir) = prep_test_dir_impl(test_full_name); - // Ensure the webserver is running. - let _ = &*WEBSERVER_HANDLE; - let now = SystemTime::now(); - let mut started = false; - while now.elapsed().unwrap() < WEBSERVER_START_TIMEOUT { - if minreq::get(format!("http://127.0.0.1:{IP_PORT}/ping")) - .send() - .is_ok_and(|response| response.as_bytes() == b"pong") - { - started = true; - break; - } - sleep(Duration::from_millis(10)).await; - } - - assert!(started, "Webserver failed to start."); // Connect to the VSCode IDE websocket. let ws_ide = connect_async_ide(connection_id).await; @@ -253,7 +243,8 @@ async fn test_vscode_ide_websocket1() { // Start a second connection; verify that it fails. let err = connect_async(format!( - "ws://127.0.0.1:{IP_PORT}/vsc/ws-ide/{connection_id}", + "ws://127.0.0.1:{}/vsc/ws-ide/{connection_id}", + *IP_PORT, )) .await .expect_err("Should fail to connect"); @@ -351,7 +342,8 @@ async fn test_vscode_ide_websocket3() { let join_handle = thread::spawn(move || { assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{file_path_str_thread}", + "http://localhost:{}/vsc/fs/{connection_id}/{file_path_str_thread}", + *IP_PORT, )) .send() .unwrap() @@ -414,7 +406,8 @@ async fn test_vscode_ide_websocket3a() { let join_handle = thread::spawn(move || { assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{file_path_str_thread}", + "http://localhost:{}/vsc/fs/{connection_id}/{file_path_str_thread}", + *IP_PORT, )) .send() .unwrap() @@ -508,7 +501,8 @@ async fn test_vscode_ide_websocket8() { let join_handle = thread::spawn(move || { assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, drop_leading_slash(&file_path_thread.to_slash().unwrap()) )) .send() @@ -617,7 +611,8 @@ async fn test_vscode_ide_websocket7() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap(), ), None, @@ -932,7 +927,8 @@ async fn test_vscode_ide_websocket13() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap(), ), None, @@ -1213,7 +1209,8 @@ async fn test_vscode_ide_websocket4() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap() ), None, @@ -1251,7 +1248,8 @@ async fn test_vscode_ide_websocket4() { // Get the file itself. assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}/{}", + *IP_PORT, test_dir_thread.to_slash().unwrap(), // On Windows, send incorrect case for this file; the server // should correct it. @@ -1344,7 +1342,8 @@ async fn test_vscode_ide_websocket4() { let join_handle = thread::spawn(move || { assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/toc.md", + "http://localhost:{}/vsc/fs/{connection_id}/{}/toc.md", + *IP_PORT, test_dir_thread.to_slash().unwrap() )) .send() @@ -1478,7 +1477,8 @@ async fn test_vscode_ide_websocket4a() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap() ), None, @@ -1521,7 +1521,8 @@ async fn test_vscode_ide_websocket4a() { let join_handle = thread::spawn(move || { // Read the file. let response = minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/{hw}", + "http://localhost:{}/vsc/fs/{connection_id}/{}/{hw}", + *IP_PORT, test_dir_thread.to_slash().unwrap(), )) .send() @@ -1580,7 +1581,8 @@ async fn test_vscode_ide_websocket4b() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap() ), None, @@ -1623,7 +1625,8 @@ async fn test_vscode_ide_websocket4b() { let join_handle = thread::spawn(move || { // Read the file. let response = minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/{hw}", + "http://localhost:{}/vsc/fs/{connection_id}/{}/{hw}", + *IP_PORT, test_dir_thread.to_slash().unwrap(), )) .send() @@ -1637,7 +1640,8 @@ async fn test_vscode_ide_websocket4b() { // Now, request the PDF as a raw file. let response = minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/{hw}?raw", + "http://localhost:{}/vsc/fs/{connection_id}/{}/{hw}?raw", + *IP_PORT, test_dir_thread.to_slash().unwrap(), )) .send() @@ -1776,7 +1780,8 @@ async fn test_vscode_ide_websocket10() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap() ), None, @@ -1813,7 +1818,8 @@ async fn test_vscode_ide_websocket10() { let join_handle = thread::spawn(move || { assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/test.py", + "http://localhost:{}/vsc/fs/{connection_id}/{}/test.py", + *IP_PORT, test_dir_thread.to_slash().unwrap(), )) .send() @@ -1985,7 +1991,8 @@ async fn fetch_sidebar_toc( // The body of the response: the page showing the TOC. ) -> String { let url = format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/toc.md?mode=toc", + "http://localhost:{}/vsc/fs/{connection_id}/{}/toc.md?mode=toc", + *IP_PORT, test_dir.to_slash().unwrap() ); let join_handle = thread::spawn(move || { @@ -2064,7 +2071,8 @@ async fn test_vscode_ide_websocket11() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap() ), None, @@ -2098,7 +2106,8 @@ async fn test_vscode_ide_websocket11() { let join_handle = thread::spawn(move || { assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/test.py", + "http://localhost:{}/vsc/fs/{connection_id}/{}/test.py", + *IP_PORT, test_dir_thread.to_slash().unwrap(), )) .send() @@ -2239,7 +2248,8 @@ async fn test_vscode_ide_websocket12() { id: INITIAL_CLIENT_MESSAGE_ID, message: EditorMessageContents::CurrentFile( format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}", + "http://localhost:{}/vsc/fs/{connection_id}/{}", + *IP_PORT, file_path.to_slash().unwrap() ), None, @@ -2273,7 +2283,8 @@ async fn test_vscode_ide_websocket12() { let join_handle = thread::spawn(move || { assert_eq!( minreq::get(format!( - "http://localhost:{IP_PORT}/vsc/fs/{connection_id}/{}/toc.md", + "http://localhost:{}/vsc/fs/{connection_id}/{}/toc.md", + *IP_PORT, test_dir_thread.to_slash().unwrap(), )) .send() diff --git a/server/src/webserver.rs b/server/src/webserver.rs index 5f5ef1ee..242c72bc 100644 --- a/server/src/webserver.rs +++ b/server/src/webserver.rs @@ -1805,8 +1805,7 @@ impl RegisterRoutes for (A, B) { // standalone CLI's `start`/`stop` subcommands. The VSCode extension embeds the // server in-process and controls its lifecycle directly via // \[`crate::ide::CodeChatEditorServer::stop_server`\], so it doesn't need these -// routes. This crate's own test harness (`ide::vscode::tests`) also registers -// them, reusing `/ping` to detect when its shared test webserver has started. +// routes. #[derive(Clone)] pub struct LifecycleRoutes; diff --git a/server/src/webserver/tests.rs b/server/src/webserver/tests.rs index 0f91c397..d8947ae3 100644 --- a/server/src/webserver/tests.rs +++ b/server/src/webserver/tests.rs @@ -34,7 +34,6 @@ use super::{path_to_url, request_path_to_file_path, try_canonicalize, url_to_pat // exercises it. #[cfg(windows)] use super::simplify; -use crate::ide::vscode::tests::IP_PORT; use test_utils::{cast, prep_test_dir}; // Tests @@ -58,7 +57,7 @@ fn test_url_to_path() { cast!( url_to_path( &format!( - "http://127.0.0.1:{IP_PORT}/fw/fsc/dummy_connection_id/{}path%20spaces/foo.py", + "http://127.0.0.1:8080/fw/fsc/dummy_connection_id/{}path%20spaces/foo.py", if cfg!(windows) { "C:/" } else { "" } ), PATH_PREFIX @@ -79,7 +78,7 @@ fn test_url_to_path() { cast!( url_to_path( &format!( - "http://127.0.0.1:{IP_PORT}/fw/fsc/dummy_connection_id/{}foo%5Cbar.py", + "http://127.0.0.1:8080/fw/fsc/dummy_connection_id/{}foo%5Cbar.py", if cfg!(windows) { "C:/" } else { "" } ), PATH_PREFIX @@ -98,7 +97,7 @@ fn test_url_to_path() { assert_eq!( url_to_path( &format!( - "http://127.0.0.1:{IP_PORT}/fw/fsc/dummy_connection_id/{test_dir_str}/test%20spaces.py" + "http://127.0.0.1:8080/fw/fsc/dummy_connection_id/{test_dir_str}/test%20spaces.py" ), PATH_PREFIX ) @@ -187,7 +186,7 @@ fn test_path_to_url_round_trip() { let url = path_to_url(URL_PREFIX, Some(CONNECTION_ID), &file_path); assert_eq!( cast!( - url_to_path(&format!("http://127.0.0.1:{IP_PORT}{url}"), PATH_PREFIX), + url_to_path(&format!("http://127.0.0.1:8080{url}"), PATH_PREFIX), Ok ), file_path, From 245c4310d7768ba953f8d92369d04615efaefae9 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 16:04:43 -0600 Subject: [PATCH 22/29] Build: run tests with cargo nextest; echo commands instead of info banners. Install cargo-nextest and use it for tests, binding exports, and coverage. Replace cmd_lib's logger with one that shows debug output (still honoring RUST_LOG), then enable cmd_lib's command echo in place of hand-written info lines. Combine the cargo binstall invocations into one. Co-Authored-By: Claude Opus 5.5 --- builder/Cargo.lock | 1 + builder/Cargo.toml | 1 + builder/src/main.rs | 59 ++++++++++-------------------- server/tests/overall/common/mod.rs | 4 +- 4 files changed, 24 insertions(+), 41 deletions(-) diff --git a/builder/Cargo.lock b/builder/Cargo.lock index 2a60e7a2..25c53281 100644 --- a/builder/Cargo.lock +++ b/builder/Cargo.lock @@ -87,6 +87,7 @@ dependencies = [ "cmd_lib", "current_platform", "dunce", + "env_logger", "path-slash", "regex", ] diff --git a/builder/Cargo.toml b/builder/Cargo.toml index 51071137..6aa020ac 100644 --- a/builder/Cargo.toml +++ b/builder/Cargo.toml @@ -42,6 +42,7 @@ clap = { version = "4", features = ["derive"] } cmd_lib = "2.0.0" current_platform = "0.2.0" dunce = "1.0.5" +env_logger = "0.11.11" path-slash = "0.2.1" regex = "1.11.1" diff --git a/builder/src/main.rs b/builder/src/main.rs index 91d39e22..aaf0b5d6 100644 --- a/builder/src/main.rs +++ b/builder/src/main.rs @@ -386,9 +386,7 @@ fn run_install(cargo_dist: bool) -> io::Result<()> { patch_client_libs()?; run_script("pnpm", &["install"], VSCODE_PATH, true)?; run_cmd!( - info "cargo fetch"; cargo fetch; - info "Builder: cargo fetch"; cargo fetch --manifest-path=$BUILDER_PATH/Cargo.toml; )?; // Install the cargo binstall binary, taken from the @@ -419,25 +417,14 @@ fn run_install(cargo_dist: bool) -> io::Result<()> { // [https://github.com/bjones1/CodeChat\_Editor/issues/157](https://github.com/bjones1/CodeChat_Editor/issues/157); // remove this workaround when the upstream issues is fixed. run_cmd!( - info "cargo binstall cargo-dist"; cargo binstall cargo-dist@${DIST_VERSION} --no-confirm --git "https://github.com/axodotdev/cargo-dist"; )?; } run_cmd!( - info "cargo binstall cargo-outdated"; - cargo binstall cargo-outdated --no-confirm; - info "cargo binstall cargo-sort"; - cargo binstall cargo-sort --no-confirm; - info "cargo binstall cargo-audit"; - cargo binstall cargo-audit --no-confirm; - info "cargo binstall cargo-machete"; - cargo binstall cargo-machete --no-confirm; - info "cargo binstall cargo-llvm-cov"; - cargo binstall cargo-llvm-cov --no-confirm; + cargo binstall cargo-audit cargo-llvm-cov cargo-machete cargo-nextest cargo-outdated cargo-sort --no-confirm; // Install the required llvm-tools component used by cargo-llvm-cov // without prompting. - info "rustup component add llvm-tools-preview"; rustup component add llvm-tools-preview; ) } @@ -447,16 +434,13 @@ fn run_update() -> io::Result<()> { patch_client_libs()?; run_script("pnpm", &["update"], VSCODE_PATH, true)?; run_cmd!( - info "cargo update"; cargo update; - info "Builder: cargo update"; cargo update --manifest-path=$BUILDER_PATH/Cargo.toml; )?; // Simply display outdated dependencies, but don't consider them an error. run_script("pnpm", &["outdated"], CLIENT_PATH, false)?; run_script("pnpm", &["outdated"], VSCODE_PATH, false)?; run_cmd!( - info "cargo outdated"; cargo outdated --workspace; )?; // `cargo outdated` 0.19.0 joins a relative `--manifest-path` onto the @@ -492,21 +476,15 @@ fn run_format_and_lint(check_only: bool) -> io::Result<()> { // the workspace root cargo would discover, so from `server/` it checks only // `server/Cargo.toml`. Passing `..` aims it at the workspace root instead. run_cmd!( - info "cargo clippy and fmt"; cargo clippy --workspace --all-targets --all-features -- $clippy_check_only; cargo fmt --all $check; - info "Builder: cargo clippy and fmt"; cargo clippy --all-targets --all-features --manifest-path=$BUILDER_PATH/Cargo.toml -- $clippy_check_only; cargo fmt --all $check --manifest-path=$BUILDER_PATH/Cargo.toml; - info "cargo audit"; cargo audit --file=../Cargo.lock --ignore $h2_advisory_ignore; - info "Builder: cargo audit"; cargo audit --file=$BUILDER_PATH/Cargo.lock --no-fetch --ignore $h2_advisory_ignore; - info "cargo sort"; cargo sort --workspace $check ..; - info "Builder: cargo sort"; cargo sort $check $BUILDER_PATH; )?; // `cargo machete` recurses into subdirectories on its own, so a single @@ -520,12 +498,10 @@ fn run_format_and_lint(check_only: bool) -> io::Result<()> { // its own arguments. if check_only { run_cmd!( - info "cargo machete"; cargo-machete --with-metadata --skip-target-dir ..; )?; } else { run_cmd!( - info "cargo machete"; cargo-machete --with-metadata --skip-target-dir --fix ..; )?; } @@ -545,7 +521,6 @@ fn run_full() -> io::Result<()> { // Verify that compiling for release produces no errors. run_cmd!( cd ..; - info "dist build"; dist build; )?; run_test() @@ -557,10 +532,8 @@ fn run_test() -> io::Result<()> { // from, and its feature resolution matches the `cargo run` which started // that executable, so nothing here needs to relink the running binary. run_cmd!( - info "cargo test"; - cargo test --workspace; - info "Builder: cargo test"; - cargo test --manifest-path=$BUILDER_PATH/Cargo.toml; + cargo nextest run --workspace; + cargo nextest run --manifest-path=$BUILDER_PATH/Cargo.toml; )?; Ok(()) } @@ -579,9 +552,9 @@ fn run_until_fail() -> io::Result<()> { // Clear the screen so only the current iteration's output is visible. print!("\x1b[2J\x1b[H"); println!("--- Iteration {iteration} ---"); - // `run_cmd!` returns an error if `cargo test` exits non-zero, which + // `run_cmd!` returns an error if `cargo nextest` exits non-zero, which // breaks out of the loop -- the same behavior as the script. - run_cmd!(cargo test --test overall).map_err(|err| { + run_cmd!(cargo nextest run --test overall).map_err(|err| { io::Error::other(format!("Test failed on iteration {iteration}: {err}")) })?; } @@ -592,7 +565,6 @@ fn run_build() -> io::Result<()> { // before it began executing, and rebuilding it here would have to relink // the running executable. run_cmd!( - info "cargo build"; cargo build --workspace; )?; // Clean out all bundled files before the rebuild. @@ -612,8 +584,7 @@ fn run_client_build( ) -> io::Result<()> { // Ensure the JavaScript data structures generated from Rust are up to date. run_cmd!( - info "cargo test export_bindings"; - cargo test export_bindings; + cargo nextest run export_bindings; )?; let esbuild = PathBuf::from_slash("node_modules/.bin/esbuild"); @@ -737,8 +708,7 @@ fn run_extensions_build( // Ensure the JavaScript data structures generated from Rust are up to date. run_cmd!( - info "cargo test export_bindings"; - cargo test export_bindings; + cargo nextest run export_bindings; )?; // The main build for the extension. @@ -858,8 +828,7 @@ fn run_postrelease(target: &str, tag: &str) -> io::Result<()> { fn run_coverage() -> io::Result<()> { run_cmd!( - info "cargo llvm-cov --open"; - cargo llvm-cov --open; + cargo llvm-cov nextest --open; ) } @@ -904,6 +873,18 @@ fn main() -> io::Result<()> { let root_path = canonicalize(root_path).unwrap(); env::set_current_dir(root_path).unwrap(); + // Replace cmd\_lib's built-in logger, which hides `debug` messages unless + // `RUST_LOG` says otherwise, with one which shows them unless `RUST_LOG` + // says otherwise. Match its format (see + // `cmd_lib::try_init_default_logger`), which omits the timestamp and + // target. + env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug")) + .format_timestamp(None) + .format_target(false) + .init(); + + // Echo all commands as they're run, to make failures easy to debug. + cmd_lib::set_debug(true); let cli = Cli::parse(); cli.run()?; diff --git a/server/tests/overall/common/mod.rs b/server/tests/overall/common/mod.rs index e14f89f1..6e7e0d52 100644 --- a/server/tests/overall/common/mod.rs +++ b/server/tests/overall/common/mod.rs @@ -488,8 +488,8 @@ macro_rules! make_test { // WebDriver down cleanly), so the failure never becomes a live unwind -- // meaning `#[should_panic]` can't detect it. `#[ignore]` is the // alternative: the test is skipped by default (so the suite stays green) - // but still compiles, and can be run explicitly with `cargo test -- - // --ignored` to check whether the bug has been fixed yet. + // but still compiles, and can be run explicitly with `cargo nextest run + // --run-ignored only` to check whether the bug has been fixed yet. ($test_name: ident, $test_core_name: ident, ignore = $reason: literal) => { #[tokio::test] #[tracing::instrument] From 6b0da96c6fc7db6df2c02e803d09384a3195950d Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 16:07:59 -0600 Subject: [PATCH 23/29] Fix: remove workaround for fixed issue. --- builder/src/main.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/builder/src/main.rs b/builder/src/main.rs index aaf0b5d6..5710768e 100644 --- a/builder/src/main.rs +++ b/builder/src/main.rs @@ -413,11 +413,8 @@ fn run_install(cargo_dist: bool) -> io::Result<()> { )?; #[cfg(not(target_os = "macos"))] - // See - // [https://github.com/bjones1/CodeChat\_Editor/issues/157](https://github.com/bjones1/CodeChat_Editor/issues/157); - // remove this workaround when the upstream issues is fixed. run_cmd!( - cargo binstall cargo-dist@${DIST_VERSION} --no-confirm --git "https://github.com/axodotdev/cargo-dist"; + cargo binstall cargo-dist@${DIST_VERSION} --no-confirm; )?; } From 423d28a6c99740d85592850a9038b458ccf1dbb1 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 16:15:23 -0600 Subject: [PATCH 24/29] Docs: cleanup. --- extensions/standalone/src/main.rs | 4 ++-- server/src/lib.rs | 17 +++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/extensions/standalone/src/main.rs b/extensions/standalone/src/main.rs index 77bc7e1d..1dba9da6 100644 --- a/extensions/standalone/src/main.rs +++ b/extensions/standalone/src/main.rs @@ -16,8 +16,8 @@ // [http://www.gnu.org/licenses](http://www.gnu.org/licenses). // // Relax a few pedantic Clippy lints for test code only; see the -// `[lints.clippy]` section in `Cargo.toml` for the full-crate (production) lint -// config. +// `[workspace.lints.clippy]` section in `Cargo.toml` for the full-crate +// (production) lint config. #![cfg_attr( test, allow( diff --git a/server/src/lib.rs b/server/src/lib.rs index b1261af0..fba030d1 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -2,21 +2,22 @@ // (C) 2024-2026 Bryan A. Jones. // // This file is part of the CodeChat Editor. The CodeChat Editor is free -// software: you can redistribute it and/or modify it under the terms of the -// GNU General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. +// software: you can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, either +// version 3 of the License, or (at your option) any later version. // // The CodeChat Editor is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for -// more details. +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +// details. // // You should have received a copy of the GNU General Public License along with // the CodeChat Editor. If not, see // [http://www.gnu.org/licenses](http://www.gnu.org/licenses). // -// Relax a few pedantic Clippy lints for test code only; see the `[lints.clippy]` -// section in `Cargo.toml` for the full-crate (production) lint config. +// Relax a few pedantic Clippy lints for test code only; see the +// `[workspace.lints.clippy]` section in `Cargo.toml` for the full-crate +// (production) lint config. #![cfg_attr( test, allow( From 26e34ef91141c74ebdc2288e0973a86414889f6c Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 17:08:58 -0600 Subject: [PATCH 25/29] Test: serialize browser tests with a nextest test group. nextest runs each test in its own process, so the in-process mutex guarding the WebDriver harness never serialized anything. Replace it with a `web-driver` test group limited to one thread, and update the docs which described running these tests with `cargo test` or sharing one web driver server. Co-Authored-By: Claude Opus 5.5 --- .config/nextest.toml | 40 ++++++++++++++++++++++++++++++ client/src/CodeChatEditor-test.mts | 2 +- server/tests/overall.rs | 9 ++++--- server/tests/overall/common/mod.rs | 32 ++++++++---------------- server/tests/overall/overall_1.rs | 3 --- server/tests/overall/overall_5.rs | 3 --- toc.md | 1 + 7 files changed, 57 insertions(+), 33 deletions(-) create mode 100644 .config/nextest.toml diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 00000000..f9fd128a --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,40 @@ +# The CodeChat Editor, a word processor for software developers.
    Copyright +# (C) 2024-2026 Bryan A. Jones. +# +# This file is part of the CodeChat Editor. +# +# The CodeChat Editor is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# The CodeChat Editor is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# the CodeChat Editor. If not, see +# [http://www.gnu.org/licenses](http://www.gnu.org/licenses). +# +# `nextest.toml` -- a cargo-nextest configuration file +# ==================================================== +# +# See the [docs](https://nexte.st/docs/configuration/) for this file. nextest +# reads it only from `.config/` in the workspace root. +# +# Browser-backed tests +# -------------------- +# +# The `overall` test binary (`server/tests/overall.rs`, which gathers the +# `overall_*.rs` modules) drives a browser through WebDriver. Overlapping +# WebDriver sessions are unreliable on macOS CI, so run these tests one at a +# time. nextest runs each test in its own process; a +# [test group](https://nexte.st/docs/configuration/test-groups/) limits how many +# of those processes run at once, while other tests still run in parallel. +[test-groups] +web-driver = { max-threads = 1 } + +[[profile.default.overrides]] +filter = "binary_id(codechat-editor-server::overall)" +test-group = "web-driver" diff --git a/client/src/CodeChatEditor-test.mts b/client/src/CodeChatEditor-test.mts index f8d4e597..8d6830d2 100644 --- a/client/src/CodeChatEditor-test.mts +++ b/client/src/CodeChatEditor-test.mts @@ -19,7 +19,7 @@ // ================================================================= // // To run tests, run [`./bt client-build`](#cc-1s8bUScadp) from the root of the -// project to build any changes to the Client, then run `cargo test --test +// project to build any changes to the Client, then run `cargo nextest run --test // overall test_client` from the `server/` directory. Or, add a `?test` // parameter to any web page served by the CodeChat Editor Server. // diff --git a/server/tests/overall.rs b/server/tests/overall.rs index 633f0200..725f8d23 100644 --- a/server/tests/overall.rs +++ b/server/tests/overall.rs @@ -26,11 +26,12 @@ //! ======================================= //! //! This file combines all the `overall_*` test modules into a single test -//! executable, so that a single instance of the web driver server is shared by -//! all of them. See `overall/common/mod.rs` for the shared test harness. +//! executable, which Cargo builds and links once instead of once per module. +//! See `overall/common/mod.rs` for the shared test harness. //! -//! To run these tests, execute `cargo test --test overall -//! ` in the `server/` directory. +//! To run these tests, execute `cargo nextest run --test overall +//! `; `.config/nextest.toml` runs them one at a time. +//! `cargo test` ignores that file and runs them concurrently. #[path = "overall/common/mod.rs"] mod common; #[path = "overall/overall_1.rs"] diff --git a/server/tests/overall/common/mod.rs b/server/tests/overall/common/mod.rs index 6e7e0d52..8d316189 100644 --- a/server/tests/overall/common/mod.rs +++ b/server/tests/overall/common/mod.rs @@ -21,20 +21,12 @@ //! testing IDE to generate commands then observe results, along with a browser //! tester. //! -//! A second challenge revolves around the lack of an async `Drop` trait: the -//! web driver server should be started before any test, left running during all -//! tests, then terminated as the test program exits. The web driver must be -//! initialized before a test then stopped at the end of that test. Both are -//! ideal for this missing Drop trait. As a workaround: -//! -//! * The web driver server relies on the C `atexit` call to stop the server. -//! However, when tests fail, this doesn't get called, leaving the server -//! running. This causes the server to fail to start on the next test run, -//! since it's still running. Therefore, errors when starting the web driver -//! server are ignored by design. -//! * Tests are run in an async block, and any panics produced inside it are -//! caught using `catch_unwind()`. The driver is shut down before returning an -//! error due to the panic. +//! Each test starts its own web driver server and browser session through +//! `WebDriver::managed`. Rust lacks an async `Drop`, so a `WebDriver` dropped +//! without first being quit falls back to a synchronous teardown that blocks +//! the async executor. To always quit explicitly, the harness runs each test in +//! an async block, catches any panic it produces using `catch_unwind()`, then +//! quits the driver before returning the test's result or panic as an error. // Imports // ------- // @@ -253,8 +245,8 @@ pub const DOC_BLOCK_CSS: &str = "#CodeChat-body .CodeChat-doc-contents"; // Time to wait for the Client's asynchronously-rendered content (see // `wait_for_stable_rect`) to settle. A doc block holding a Graphviz or Mermaid -// diagram grows by hundreds of pixels when that diagram appears, and CI runs -// three OS jobs whose `cargo test` threads each drive their own browser, so +// diagram grows by hundreds of pixels when that diagram appears, and on CI +// nextest runs the workspace's other tests alongside the browser tests, so // allow generously for a loaded runner. const RENDER_TIMEOUT: Duration = Duration::from_secs(20); @@ -266,15 +258,12 @@ const RENDER_POLL_INTERVAL: Duration = Duration::from_millis(100); // require a third. const STABLE_RECT_SAMPLES: usize = 3; -// Browser-backed tests share a single WebDriver endpoint. Safari on macOS CI is -// unreliable with overlapping sessions, so serialize the harness. -pub(crate) static WEB_DRIVER_TEST_LOCK: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(()); - // ### Test harness // // A test harness. It runs the webdriver, the Server, opens the Client, then // runs provided tests. After testing finishes, it cleans up (handling panics -// properly). +// properly). Tests using this harness must not run concurrently; +// `.config/nextest.toml` runs them one at a time. pub async fn harness< F: FnOnce(CodeChatEditorServerLog, WebDriver, PathBuf) -> Fut, Fut: Future>, @@ -283,7 +272,6 @@ pub async fn harness< // The output from calling `prep_test_dir!()`. prep_test_dir: (TempDir, PathBuf), ) -> Result<(), Box> { - let _webdriver_test_lock = WEB_DRIVER_TEST_LOCK.lock().await; // Send log events to the tracing subscriber, since the code currently uses // a log-based framework. As below, ignore re-initialization errors. let _ = LogTracer::init(); diff --git a/server/tests/overall/overall_1.rs b/server/tests/overall/overall_1.rs index 5c946605..37ff7169 100644 --- a/server/tests/overall/overall_1.rs +++ b/server/tests/overall/overall_1.rs @@ -20,9 +20,6 @@ //! These are functional tests of the overall system, performed by attaching a //! testing IDE to generate commands then observe results, along with a browser //! tester. -//! -//! To run this test, execute `cargo test --test overall -//! ` in the `server/` directory. // Imports // ------- // diff --git a/server/tests/overall/overall_5.rs b/server/tests/overall/overall_5.rs index a2a15a4e..49dc4918 100644 --- a/server/tests/overall/overall_5.rs +++ b/server/tests/overall/overall_5.rs @@ -20,9 +20,6 @@ //! These are functional tests of the overall system, performed by attaching a //! testing IDE to generate commands then observe results, along with a browser //! tester. -//! -//! To run this test, execute `cargo test --test overall ` -//! in the `server/` directory. // Imports // ------- // diff --git a/toc.md b/toc.md index 5803bdc7..809a4395 100644 --- a/toc.md +++ b/toc.md @@ -138,6 +138,7 @@ Implementation * Misc * [Cargo.toml](Cargo.toml) - workspace manifest * [config.toml](.cargo/config.toml) - for Rust code coverage + * [nextest.toml](.config/nextest.toml) * [dist-workspace.toml](dist-workspace.toml) - cargo-dist configuration * [.ignore](.ignore) - show hidden directories to the CodeChat Editor From d0de1d5779d99fa08b940ea39732ac595100dc97 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 17:10:14 -0600 Subject: [PATCH 26/29] Fix: move to released dprint; update htmd version. --- Cargo.lock | 11 ++++++----- server/Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 53c5a374..ac9092ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,9 +1119,9 @@ dependencies = [ [[package]] name = "dprint-core" -version = "0.69.1" +version = "0.75.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67359cea061dd052fca921d3589a9ce59bc16fa23bfb9d06d5c669a1dbd23915" +checksum = "41d1b3e059b1b7519ef780acfa054650c095c7a6550e48f5da3a6f3ade945f6b" dependencies = [ "bumpalo", "hashbrown 0.15.5", @@ -1143,8 +1143,9 @@ dependencies = [ [[package]] name = "dprint-plugin-markdown" -version = "0.23.3" -source = "git+https://github.com/bjones1/dprint-plugin-markdown.git?branch=all-fixes#e5908d54a20e80835f36ca63abba9e6fd76e946a" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fcedde4897c3659559444971c1d6110f79635fe2a4521e811480023c05c8fb7" dependencies = [ "dprint-core", "dprint-core-macros", @@ -1529,7 +1530,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "htmd" version = "0.5.5" -source = "git+https://github.com/bjones1/htmd.git?branch=dom-interface#2ee01b1603d596df48f8e00261dc10f87dd686e2" +source = "git+https://github.com/bjones1/htmd.git?branch=dom-interface#8fd5a8bac5d8302910e2b26c0a50ff2922ee833f" dependencies = [ "html5ever 0.39.0", "markup5ever_rcdom", diff --git a/server/Cargo.toml b/server/Cargo.toml index 60b2be97..3e905e49 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -51,7 +51,7 @@ actix-ws = "0.4" ammonia = "4.1.2" bytes = { version = "1", features = ["serde"] } chrono = { version = "0.4", features = ["serde"] } -dprint-plugin-markdown = { git = "https://github.com/bjones1/dprint-plugin-markdown.git", branch = "all-fixes" } +dprint-plugin-markdown = "0.29" dunce = "1.0.5" futures-util = "0.3.29" htmd = { git = "https://github.com/bjones1/htmd.git", branch = "dom-interface", version = "0.5" } From 8342bd41e3ff67ad88f3eea3b4b23b9a446dad17 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 21:05:52 -0600 Subject: [PATCH 27/29] Fix: recent update changed indents in package.json5. --- builder/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder/src/main.rs b/builder/src/main.rs index 5710768e..7e9a10be 100644 --- a/builder/src/main.rs +++ b/builder/src/main.rs @@ -756,7 +756,7 @@ fn run_change_version(new_version: &String) -> io::Result<()> { )?; search_and_replace_file( format!("{CLIENT_PATH}/package.json5"), - r"(\r?\n version: ')[\d.]+(?:-[a-z\d]*)?(',\r?\n)", + r"(\r?\n version: ')[\d.]+(?:-[a-z\d]*)?(',\r?\n)", &replacement_string, )?; Ok(()) From ea31f9ce9207f15d088befdd82029db3759a8bc5 Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 21:39:14 -0600 Subject: [PATCH 28/29] Freeze for release --- .github/workflows/release.yml | 2 +- CHANGELOG.md | 3 + Cargo.lock | 256 +++++------ Cargo.toml | 2 +- builder/Cargo.lock | 55 +-- builder/src/main.rs | 2 +- client/package.json5 | 164 +++---- client/pnpm-lock.yaml | 460 ++++++++++--------- dist-workspace.toml | 9 +- extensions/VSCode/package.json | 6 +- extensions/VSCode/pnpm-lock.yaml | 745 +++++++++++++++---------------- server/Cargo.toml | 4 +- 12 files changed, 823 insertions(+), 885 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7f013f1e..c4e0ccf9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -64,7 +64,7 @@ jobs: # we specify bash to get pipefail; it guards against the `curl` command # failing. otherwise `sh` won't catch that `curl` returned non-0 shell: bash - run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.33.1/cargo-dist-installer.sh | sh" + run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.34.0/cargo-dist-installer.sh | sh" - name: Cache dist uses: actions/upload-artifact@v7 with: diff --git a/CHANGELOG.md b/CHANGELOG.md index ce1f7025..d14331bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ Changelog [Github master](https://github.com/bjones1/CodeChat_Editor) ----------------------------------------------------------- +Version 0.3.2 -- 2026-Nov-09 +---------------------------- + * Changed `` to support optional content. * Close an unclosed tag, comment, or declaration at the end of its doc block, instead of letting it hide or move later doc blocks. diff --git a/Cargo.lock b/Cargo.lock index ac9092ee..db014e75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,14 +90,14 @@ checksum = "367f814ad4afbac74f07df5001214da65f65e185c90ef56c4dd8df23f8695b9b" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] name = "actix-router" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f8c75c51892f18d9c46150c5ac7beb81c95f78c8b83a634d49f4ca32551fe7" +checksum = "125f4331c1f10734a96c038bc7503dff22d8ccd5f82b214e6696728561ef1149" dependencies = [ "bytestring", "cfg-if", @@ -208,7 +208,7 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -228,9 +228,9 @@ dependencies = [ [[package]] name = "actix-ws" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "decf53c3cdd63dd6f289980b430238f9a2f6d19f8bce8e418272e08d3da43f0f" +checksum = "4a3f616b2d7a52399b2156ab97024d5543e80ac70621f010e256c0de5277a600" dependencies = [ "actix-codec", "actix-http", @@ -298,7 +298,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f45dfa685e1ec33b1bf1a3b93b8047cbdbef41b6040deebbe6bea7720a45574" dependencies = [ "cssparser 0.38.0", - "html5ever 0.40.1", + "html5ever", "maplit", "url", ] @@ -368,11 +368,20 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" +[[package]] +name = "ar_archive_writer" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cd58deff2140a0a8eae87e417bd01db68a33e148aa93d1e8cd837e55e312b6" +dependencies = [ + "object", +] + [[package]] name = "arc-swap" -version = "1.9.3" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380962b3d93b99642e50b9febf72c071e97e8b32d86eae9cf4ef582bb960ae6e" +checksum = "84a22b5d51209f6de83d37a0b33d320acb8da88823e42a94c075140708f032a5" dependencies = [ "rustversion", ] @@ -424,7 +433,7 @@ checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -512,9 +521,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "6.2.0" +version = "6.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34c6783f42c21c952ad7112b354f0ba2f10760e9decea5b1b60523d6e270faaf" +checksum = "75c74c9c51b9140663e196b5fb88bc94c334d7a497c8311cb759d8557874747f" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -551,9 +560,9 @@ dependencies = [ [[package]] name = "bytestring" -version = "1.5.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86566c496f2f47d9b8147a4c8b02ffdb69c919fe0c2b2e7195d22cbba0e635c9" +checksum = "ca79160522b4aed4a69bab673bee78d3884d44240c78c96cb04b7557d532b4dc" dependencies = [ "bytes", ] @@ -569,9 +578,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86e055fa6e3e40ad6187ba25b6855eeb635d5271f8e0f0e1e9a5826b8d75bea0" +checksum = "4ff2a8126fff0f8c839080d619675a585e61720bb12d2baceae45769fd66f155" dependencies = [ "find-msvc-tools", "jobserver", @@ -653,7 +662,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -682,7 +691,7 @@ dependencies = [ [[package]] name = "codechat-editor-server" -version = "0.3.2" +version = "0.3.3" dependencies = [ "actix-files", "actix-rt", @@ -700,7 +709,7 @@ dependencies = [ "futures", "futures-util", "htmd", - "html5ever 0.39.0", + "html5ever", "htmlize", "ignore", "imara-diff", @@ -743,7 +752,7 @@ dependencies = [ [[package]] name = "codechat-editor-standalone" -version = "0.3.2" +version = "0.3.3" dependencies = [ "actix-http", "actix-rt", @@ -771,7 +780,7 @@ dependencies = [ [[package]] name = "codechat-editor-vscode-extension" -version = "0.3.2" +version = "0.3.3" dependencies = [ "codechat-editor-server", "log", @@ -844,6 +853,15 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "constant_time_eq" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb6feb175df65d0a3ccd3e73484e940d0ac664e8034f0519fd49a93db3071d9" +dependencies = [ + "rustversion", +] + [[package]] name = "convert_case" version = "0.6.0" @@ -921,9 +939,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.5.3" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba106e844045ddc02c20768ac4b0b7cb45f2cc2ecbd833ac9f5dacb183c2055" +checksum = "5f97d3416d5337d15c4b0d78c8c91df922ca143f57ec20e2d1c188333047ef04" dependencies = [ "cfg-if", ] @@ -1002,7 +1020,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d045de693cb712d0b22c6a64be5b953f67b3ce00ab5ad3dd5d8b441886ab8e1a" dependencies = [ "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -1114,7 +1132,7 @@ checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -1268,9 +1286,9 @@ checksum = "1c66915cc5391097de7a2b0b972e8505aa33c0df401fd3a6811dbdb32881ba48" [[package]] name = "flate2" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb" +checksum = "626d4928326b646e70f65ed36fc7cf9f206bdb68a0019ee7c6b4709da4e084c4" dependencies = [ "crc32fast", "miniz_oxide", @@ -1386,7 +1404,7 @@ checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -1530,23 +1548,13 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "htmd" version = "0.5.5" -source = "git+https://github.com/bjones1/htmd.git?branch=dom-interface#8fd5a8bac5d8302910e2b26c0a50ff2922ee833f" +source = "git+https://github.com/bjones1/htmd.git?branch=dom-interface#2de84a062d53f6f24af162d130c4338b9669b915" dependencies = [ - "html5ever 0.39.0", + "html5ever", "markup5ever_rcdom", "phf 0.14.0", ] -[[package]] -name = "html5ever" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8" -dependencies = [ - "log", - "markup5ever 0.39.0", -] - [[package]] name = "html5ever" version = "0.40.1" @@ -1554,7 +1562,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456a1a377e608e555d22ddab27ac0114bc7a7b4199078108e34c2aeae6c9b130" dependencies = [ "log", - "markup5ever 0.40.0", + "markup5ever", "memchr", ] @@ -1985,9 +1993,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +checksum = "3bd1574e617a9a6c1f8f8181bd7e841e1f20e4277607ef28945765188d6284d4" [[package]] name = "jni" @@ -2214,9 +2222,9 @@ checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" [[package]] name = "local-channel" -version = "0.1.5" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" +checksum = "3c689de2ea71f5bcc468eaddb30650a9b5d143739fc42569e571691551ac83dc" dependencies = [ "futures-core", "futures-sink", @@ -2225,9 +2233,9 @@ dependencies = [ [[package]] name = "local-waker" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" +checksum = "88bab6b3971cb9cda8a370672a73e59a442b87552f005fb60ec07b67fa658f13" [[package]] name = "lock_api" @@ -2303,17 +2311,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" -[[package]] -name = "markup5ever" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" -dependencies = [ - "log", - "tendril", - "web_atoms 0.2.6", -] - [[package]] name = "markup5ever" version = "0.40.0" @@ -2322,17 +2319,17 @@ checksum = "0ab3dc68ac4a0f5719e560136778c1ee716e296030d75dbd4484e37e39e3a842" dependencies = [ "log", "tendril", - "web_atoms 0.3.0", + "web_atoms", ] [[package]] name = "markup5ever_rcdom" -version = "0.39.0+unofficial" +version = "0.40.1+unofficial" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ac010f19d6c4af81eeb4018a39d7a115de9d285af45c126a4ac02e6fc5716b7" +checksum = "64206f12eb431c03d9b6f293846f8b0517578905b6c0cac266aa52f09c11ad7c" dependencies = [ - "html5ever 0.39.0", - "markup5ever 0.39.0", + "html5ever", + "markup5ever", "tendril", "xml5ever", ] @@ -2354,9 +2351,9 @@ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "mime" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "d5848f5a9e8117cf94f2f90faac24a87ff81600ff8628c1e3deaab572e76bfa1" [[package]] name = "mime_guess" @@ -2479,7 +2476,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -2492,7 +2489,7 @@ dependencies = [ "proc-macro2", "quote", "semver", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -2548,9 +2545,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "notify" -version = "8.2.1" +version = "8.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82f812702fbc75d35416d3f884e04925be7e9498f4eceea2e24ba34559284674" +checksum = "c41a04a5f59df9322cc657286dd2d79f90816119b22c5f847607c850110205ab" dependencies = [ "bitflags", "inotify", @@ -2580,9 +2577,9 @@ dependencies = [ [[package]] name = "notify-types" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a437a9308232ce794b1e7fdf540d38ea37efc3c73492640c13b4c8568b8f108" +checksum = "8c491a384baf9fec20df565cdb8138a12809d4c7439763b566eb8114c5d59979" dependencies = [ "bitflags", ] @@ -2688,6 +2685,15 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "object" +version = "0.39.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.21.4" @@ -3194,7 +3200,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -3208,9 +3214,9 @@ dependencies = [ [[package]] name = "pest_stack_guard" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e6cd2217057fa86b6eaa512917e58089d875b957a31e35e7ab729977e0a5f2" +checksum = "9ac6154fd4418b8f0b82532c59c26f303f9ca59a64c883e8ce3971fd82733439" dependencies = [ "psm", "stacker", @@ -3467,10 +3473,11 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.24" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" +checksum = "4dcd034599e63b970727f70d79e02d62390a4a84f7c6b827c27c46d5ac3fa622" dependencies = [ + "ar_archive_writer", "cc", ] @@ -3993,7 +4000,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -4019,7 +4026,7 @@ checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -4130,9 +4137,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.16.4" +version = "1.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d5d4b1981b8bbbb7aed204cae5726d683d5d6ac7e74ec54122ea28f315e7c8" +checksum = "149309498a5f7334b12ddae0cad8aba81ce785fe91755068867e017cf98fee46" [[package]] name = "smawk" @@ -4175,19 +4182,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "string_cache" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared 0.13.1", - "precomputed-hash", - "serde", -] - [[package]] name = "string_cache" version = "0.11.0" @@ -4198,18 +4192,7 @@ dependencies = [ "parking_lot", "phf_shared 0.14.0", "precomputed-hash", -] - -[[package]] -name = "string_cache_codegen" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" -dependencies = [ - "phf_generator 0.13.1", - "phf_shared 0.13.1", - "proc-macro2", - "quote", + "serde", ] [[package]] @@ -4269,9 +4252,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +checksum = "4ae9ccbea3a7b0b09443036490c8f34a8b1b760fd345e5c0dae0aac718faea79" dependencies = [ "proc-macro2", "quote", @@ -4295,7 +4278,7 @@ checksum = "901704edd0dfe137f1987838ee4f259e4e063c31371bdb423f7ae38ec6f77f02" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -4407,7 +4390,7 @@ checksum = "94196cd236b8087d4059b7cfba1e1c864f20262ecb38aa7b1da9e66d6f07ab77" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -4447,7 +4430,7 @@ checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -4541,7 +4524,7 @@ checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -4985,7 +4968,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", "wasm-bindgen-shared", ] @@ -5031,18 +5014,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "web_atoms" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba8b815c1b593dc0baf78dd0f4fc8fdb2de53198fb1163738093e9a311c33fb3" -dependencies = [ - "phf 0.13.1", - "phf_codegen 0.13.1", - "string_cache 0.9.0", - "string_cache_codegen 0.6.1", -] - [[package]] name = "web_atoms" version = "0.3.0" @@ -5051,8 +5022,8 @@ checksum = "7572660c8890448ba236b7376f27e389c6a7e1c70195622faced601f855c0ada" dependencies = [ "phf 0.14.0", "phf_codegen 0.14.0", - "string_cache 0.11.0", - "string_cache_codegen 0.11.2", + "string_cache", + "string_cache_codegen", ] [[package]] @@ -5467,12 +5438,12 @@ dependencies = [ [[package]] name = "xml5ever" -version = "0.39.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab627f34ff61b80d756180d556f9c68801d836d271b3b8c094504ceca69d221" +checksum = "73290529dc9bc6c6155bf77fdd70ce0061f98ad387586aa3104cddab29206961" dependencies = [ "log", - "markup5ever 0.39.0", + "markup5ever", ] [[package]] @@ -5500,7 +5471,7 @@ checksum = "ec8ebde2db3681e8c9980cc27822030e68752690ddfa9473e739aeb4dbde6d71" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", "synstructure", ] @@ -5541,7 +5512,7 @@ checksum = "f75b4683f6c7f45248d4d64056a24298c6281e0993356d7d1b4a1a962ef10d4a" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", "synstructure", ] @@ -5550,6 +5521,20 @@ name = "zeroize" version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13084392c5e4bc371903e2935a5eaeed24905a7511356b883835e18a78f6879" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] name = "zerotrie" @@ -5583,23 +5568,26 @@ checksum = "c3743ddbf47738d929cd1ae2e199d40d0162979dfe31aef8ae646d2bf00bf97a" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] name = "zip" -version = "9.2.0" +version = "9.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f5b58784007ff6e5f280ec82c8596686a3b9b5dd5836c63288d4479f84728b9" +checksum = "0700e6c427aff64acdbf02e85fbfd946c2ee12319d1af013092f3a2178914ff8" dependencies = [ + "constant_time_eq", "crc32fast", "flate2", "getrandom 0.4.3", "indexmap", + "libc", "memchr", "nix", "typed-path", "windows-sys 0.61.2", + "zeroize", "zopfli", ] diff --git a/Cargo.toml b/Cargo.toml index ba2d2209..3c763230 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,7 +61,7 @@ homepage = "https://codechat-editor.onrender.com/fw/fsb/opt/render/project/src/R keywords = ["literate programming"] license = "GPL-3.0-only" repository = "https://github.com/bjones1/CodeChat_Editor" -version = "0.3.2" +version = "0.3.3" # Shared dependencies # ------------------- diff --git a/builder/Cargo.lock b/builder/Cargo.lock index 25c53281..b560bf37 100644 --- a/builder/Cargo.lock +++ b/builder/Cargo.lock @@ -129,7 +129,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -174,37 +174,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a74858bcfe44b22016cb49337d7b6f04618c58e5dbfdef61b06b8c434324a0bc" -[[package]] -name = "defmt" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a0795ac740cb54d7b3775c9c17345f6aaecf884c01733b39d6017738e0e3e1" -dependencies = [ - "bitflags", - "defmt-macros", -] - -[[package]] -name = "defmt-macros" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "840bb056bd99c495c9188198a258ab787c79f306d864db3e6e8451442d6d8366" -dependencies = [ - "defmt-parser", - "proc-macro2", - "quote", - "syn 3.0.9", -] - -[[package]] -name = "defmt-parser" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71958f69fb2de856c5dd51ac9377e986ca1aa5919f931bf5395a807277f889a0" -dependencies = [ - "thiserror", -] - [[package]] name = "dunce" version = "1.0.5" @@ -259,11 +228,10 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "jiff" -version = "0.2.38" +version = "0.2.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b005715dcbeb0089a3c0dab99f2ff1cc3b2525323552703d648585d342a383" +checksum = "fefca06093eeaed707a905795e68206da0edca4edef23d2a3997a3ddbee462aa" dependencies = [ - "defmt", "jiff-core", "jiff-static", "log", @@ -274,19 +242,18 @@ dependencies = [ [[package]] name = "jiff-core" -version = "0.1.1" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c" +checksum = "77a24020db0ee88d1c681d677681bd31f9f4ea189a455425223d52ce4f1508aa" dependencies = [ - "defmt", "log", ] [[package]] name = "jiff-static" -version = "0.2.38" +version = "0.2.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc9817253cf7c7ee4684451bd327e88d6f3658014e54a29198625590650695c" +checksum = "41d3213549742662eea1a18e6c5af9be5dfbabeb7611ab71356a54928ec398f0" dependencies = [ "jiff-core", "proc-macro2", @@ -441,7 +408,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] @@ -463,9 +430,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.9" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b" +checksum = "4ae9ccbea3a7b0b09443036490c8f34a8b1b760fd345e5c0dae0aac718faea79" dependencies = [ "proc-macro2", "quote", @@ -489,7 +456,7 @@ checksum = "fe5197923287db20a58125f0bc85c062f7f2c892de97b18c356f9efb14b28524" dependencies = [ "proc-macro2", "quote", - "syn 3.0.9", + "syn 3.0.10", ] [[package]] diff --git a/builder/src/main.rs b/builder/src/main.rs index 7e9a10be..b212989b 100644 --- a/builder/src/main.rs +++ b/builder/src/main.rs @@ -144,7 +144,7 @@ static WORKSPACE_MANIFEST_PATH: &str = "../Cargo.toml"; // second, explicit pass over it. static BUILDER_PATH: &str = "../builder"; static NAPI_TARGET: &str = "NAPI_TARGET"; -static DIST_VERSION: &str = "0.33.1"; +static DIST_VERSION: &str = "0.34.0"; // Code // ---- diff --git a/client/package.json5 b/client/package.json5 index 361c26e3..744e2e5c 100644 --- a/client/package.json5 +++ b/client/package.json5 @@ -24,86 +24,86 @@ oddly munged by `pnpm` per [this issue](https://github.com/pnpm/pnpm/issues/9838). */ { - author: 'Bryan A. Jones', - categories: [ - 'Other', - ], - description: 'The CodeChat Editor Client, part of a web-based literate programming editor (the CodeChat Editor).', - homepage: 'https://codechat-editor.onrender.com/fw/fsb/opt/render/project/src/README.md', - keywords: [ - 'literate programming', - 'CodeChat Editor', - 'Visual Studio Code extension', - ], - license: 'GPL-3.0-only', - name: 'codechat-editor-client', - repository: { - type: 'git', - url: 'https://github.com/bjones1/CodeChat_editor', - }, - type: 'module', - version: '0.3.2', - dependencies: { - '@codemirror/commands': '^6.11.1', - '@codemirror/lang-cpp': '^6.0.3', - '@codemirror/lang-css': '^6.3.1', - '@codemirror/lang-go': '^6.0.1', - '@codemirror/lang-html': '^6.4.12', - '@codemirror/lang-java': '^6.0.2', - '@codemirror/lang-javascript': '^6.2.5', - '@codemirror/lang-json': '^6.0.2', - '@codemirror/lang-python': '^6.2.1', - '@codemirror/lang-rust': '^6.0.2', - '@codemirror/lang-sql': '^6.10.0', - '@codemirror/lang-yaml': '^6.1.3', - '@codemirror/language': '^6.13.1', - '@codemirror/legacy-modes': '^6.5.5', - '@codemirror/lint': '^6.9.7', - '@codemirror/state': '^6.7.6', - '@codemirror/view': '^6.43.15', - '@hpcc-js/wasm-graphviz': '^1.30.0', - '@mathjax/mathjax-newcm-font': '^4.1.3', - codemirror: '^6.0.2', - mathjax: '^4.1.3', - mermaid: '^12.2.0', - 'pdfjs-dist': '^6.4.299', - tinymce: '^8.10.1', - 'toastify-js': '^1.12.0', - }, - devDependencies: { - '@eslint/css': '^2.0.1', - '@eslint/js': '^10.0.1', - '@types/chai': '^5.2.3', - '@types/mocha': '^10.0.10', - '@types/node': '^26.6.6', - '@types/toastify-js': '^1.12.4', - '@typescript-eslint/eslint-plugin': '^8.72.1', - '@typescript-eslint/parser': '^8.72.1', - '@typescript/native': 'npm:typescript@^7.0.2', - /* The accessibility audit engine driven by the Server's `overall_a11y` - browser tests. */ - 'axe-core': '^4.14.0', - chai: '^6.3.0', - esbuild: '^0.28.2', - eslint: '^10.14.0', - 'eslint-config-prettier': '^10.1.8', - 'eslint-plugin-import': '^2.32.0', - 'eslint-plugin-prettier': '^5.5.7', - globals: '^17.13.0', - mocha: '^12.0.3', - 'npm-check-updates': '^23.1.1', - prettier: '^3.9.10', - /* Typescript 7 support for eslint is blocked per - [this issue](https://github.com/typescript-eslint/typescript-eslint/issues/10940). - Instead, see - [Running Typescript 7.0 Side-by-Side with TypeScript 6.0](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#running-side-by-side-with-typescript-6.0) - for a workaround. */ - typescript: 'npm:@typescript/typescript6@^6.0.2', - 'typescript-eslint': '^8.72.1', - }, - scripts: { - test: 'echo "Error: no test specified" && exit 1', - build: 'cargo run --manifest-path=../builder/Cargo.toml client-build', - dist: 'cargo run --manifest-path=../builder/Cargo.toml client-build --dist', - }, + author: 'Bryan A. Jones', + categories: [ + 'Other', + ], + description: 'The CodeChat Editor Client, part of a web-based literate programming editor (the CodeChat Editor).', + homepage: 'https://codechat-editor.onrender.com/fw/fsb/opt/render/project/src/README.md', + keywords: [ + 'literate programming', + 'CodeChat Editor', + 'Visual Studio Code extension', + ], + license: 'GPL-3.0-only', + name: 'codechat-editor-client', + repository: { + type: 'git', + url: 'https://github.com/bjones1/CodeChat_editor', + }, + type: 'module', + version: '0.3.3', + dependencies: { + '@codemirror/commands': '^6.11.1', + '@codemirror/lang-cpp': '^6.0.3', + '@codemirror/lang-css': '^6.3.1', + '@codemirror/lang-go': '^6.0.1', + '@codemirror/lang-html': '^6.4.12', + '@codemirror/lang-java': '^6.0.2', + '@codemirror/lang-javascript': '^6.2.5', + '@codemirror/lang-json': '^6.0.2', + '@codemirror/lang-python': '^6.2.1', + '@codemirror/lang-rust': '^6.0.2', + '@codemirror/lang-sql': '^6.10.0', + '@codemirror/lang-yaml': '^6.1.3', + '@codemirror/language': '^6.13.1', + '@codemirror/legacy-modes': '^6.5.5', + '@codemirror/lint': '^6.9.7', + '@codemirror/state': '^6.7.6', + '@codemirror/view': '^6.43.15', + '@hpcc-js/wasm-graphviz': '^1.30.0', + '@mathjax/mathjax-newcm-font': '^4.1.3', + codemirror: '^6.0.2', + mathjax: '^4.1.3', + mermaid: '^12.3.0', + 'pdfjs-dist': '^6.5.438', + tinymce: '^8.10.1', + 'toastify-js': '^1.12.0', + }, + devDependencies: { + '@eslint/css': '^2.0.1', + '@eslint/js': '^10.0.1', + '@types/chai': '^5.2.3', + '@types/mocha': '^10.0.10', + '@types/node': '^26.6.6', + '@types/toastify-js': '^1.12.4', + '@typescript-eslint/eslint-plugin': '^8.72.1', + '@typescript-eslint/parser': '^8.72.1', + '@typescript/native': 'npm:typescript@^7.0.2', + /* The accessibility audit engine driven by the Server's `overall_a11y` + browser tests. */ + 'axe-core': '^4.14.0', + chai: '^6.3.0', + esbuild: '^0.28.2', + eslint: '^10.14.0', + 'eslint-config-prettier': '^10.1.8', + 'eslint-plugin-import': '^2.32.0', + 'eslint-plugin-prettier': '^5.5.7', + globals: '^17.14.0', + mocha: '^12.0.3', + 'npm-check-updates': '^23.1.1', + prettier: '^3.9.10', + /* Typescript 7 support for eslint is blocked per + [this issue](https://github.com/typescript-eslint/typescript-eslint/issues/10940). + Instead, see + [Running Typescript 7.0 Side-by-Side with TypeScript 6.0](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/#running-side-by-side-with-typescript-6.0) + for a workaround. */ + typescript: 'npm:@typescript/typescript6@^6.0.2', + 'typescript-eslint': '^8.72.1', + }, + scripts: { + test: 'echo "Error: no test specified" && exit 1', + build: 'cargo run --manifest-path=../builder/Cargo.toml client-build', + dist: 'cargo run --manifest-path=../builder/Cargo.toml client-build --dist', + }, } diff --git a/client/pnpm-lock.yaml b/client/pnpm-lock.yaml index 9623b575..15dd7fdd 100644 --- a/client/pnpm-lock.yaml +++ b/client/pnpm-lock.yaml @@ -72,11 +72,11 @@ importers: specifier: ^4.1.3 version: 4.1.3 mermaid: - specifier: ^12.2.0 - version: 12.2.0 + specifier: ^12.3.0 + version: 12.3.0 pdfjs-dist: - specifier: ^6.4.299 - version: 6.4.299 + specifier: ^6.5.438 + version: 6.5.438 tinymce: specifier: ^8.10.1 version: 8.10.1 @@ -133,8 +133,8 @@ importers: specifier: ^5.5.7 version: 5.5.7(eslint-config-prettier@10.1.8(eslint@10.14.0(supports-color@8.1.1)))(eslint@10.14.0(supports-color@8.1.1))(prettier@3.9.10) globals: - specifier: ^17.13.0 - version: 17.13.0 + specifier: ^17.14.0 + version: 17.14.0 mocha: specifier: ^12.0.3 version: 12.0.3 @@ -405,8 +405,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + '@eslint-community/regexpp@4.12.3': + resolution: {integrity: sha512-R76UKbvsqI68DJJVTVyqFKqU98CN4+B+acxNfEA2IFarSzP0SjtKf/3+fFiXzTyv5Fj3PxLkGHe2wnVWWMxobQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.23.5': @@ -1030,8 +1030,8 @@ packages: codemirror@6.0.2: resolution: {integrity: sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==} - commander@15.0.0: - resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} + commander@15.1.0: + resolution: {integrity: sha512-cgnQ88TRrWcC7pVq46RzJVRMktu3W2RcbnoidnfBsl1bmDCBwJS/udcIZpKoCrbAYYaCqsz1yZCVIgbIaU3ddQ==} engines: {node: '>=22.12.0'} commander@7.2.0: @@ -1071,140 +1071,140 @@ packages: d3-array@2.12.1: resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} - d3-array@3.2.4: - resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + d3-array@3.2.5: + resolution: {integrity: sha512-Th8qGXoBalmWsstpkuhmBuTsBQIFqYOJtjlBvNVvBfJ8E3uYusBUwUR8HU20U0qKKQkgCvKyR1YjiozWadk5QA==} engines: {node: '>=12'} - d3-axis@3.0.0: - resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + d3-axis@3.0.1: + resolution: {integrity: sha512-E5QCXfaf/uJZEHHiqoWRq+bQEm2PzoVFv2rDC7CZ3wwI0MjfMW3w83J3ubobG4IJj3lShAI5eiPJhOu/8wHofA==} engines: {node: '>=12'} - d3-brush@3.0.0: - resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + d3-brush@3.0.1: + resolution: {integrity: sha512-L5Glqa/Gb7LU3ndIOMtA5mDzlJ0aXKp5ELP2X09ctWF23jO7+faIUVDbmaIi+D6k3EemXFWn1F3lkfguExoVhA==} engines: {node: '>=12'} - d3-chord@3.0.1: - resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + d3-chord@3.0.2: + resolution: {integrity: sha512-cGmADo5M2PTi3ewJZ2lcE32eURd4JmHtQ5JwRIUcas5L1SXqufG9yPyjWp8fW0gRi7aZi9bgbZPFZO1eyZ+1CQ==} engines: {node: '>=12'} - d3-color@3.1.0: - resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + d3-color@3.1.1: + resolution: {integrity: sha512-lfab8x0Bj0UO7SNsY8dZSbNIA6ipbkE3X0NG9nqjCu6CfCHZseuDnOSJY7hidKrjpP++i1M2qT+FlAdPKYRilA==} engines: {node: '>=12'} - d3-contour@4.0.2: - resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + d3-contour@4.0.3: + resolution: {integrity: sha512-5DYURc8KwXPOhSUBblU0P9rVcArsSPxPOxsfO0Eud0s28oU0sB2e80aRHRL9AZW3usT8ikFKyIHpHHLNWLdRVA==} engines: {node: '>=12'} - d3-delaunay@6.0.4: - resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + d3-delaunay@6.0.6: + resolution: {integrity: sha512-DMQIEvSJhZCB6pwedcXaAlQ+MeKU5LlM2XakKtc73b/VM+RBiI1SRXycOEOKg2jsKj4zZ9F0KGYG6nCGwwWu/g==} engines: {node: '>=12'} - d3-dispatch@3.0.1: - resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + d3-dispatch@3.0.2: + resolution: {integrity: sha512-sAzH4Y4nsLo8eSqw5jKiZt+LU2wZmL/qS+OkxQGjhwazB/D7TY34R/QK1eshfGr7cZEKymKZ/Haem7m+lu98Sg==} engines: {node: '>=12'} - d3-drag@3.0.0: - resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + d3-drag@3.0.1: + resolution: {integrity: sha512-OWeoayCq8J69hUIjvL+Mb6Q6Oaj/fyHV5XaXByEUAG+JUjIfTGDnk3qGpcXrD3VmQ3BSV96fcbM6fqq7C0tbPA==} engines: {node: '>=12'} - d3-dsv@3.0.1: - resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + d3-dsv@3.0.2: + resolution: {integrity: sha512-FUnXhX7I4/AXyRCZzwfZTDGSq8PGZ4oR0tiCBqNGOZMsDrQ+6sIWNQnBzcCGhzJKZ6uCvCezTwflUqI209RRiQ==} engines: {node: '>=12'} hasBin: true - d3-ease@3.0.1: - resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + d3-ease@3.0.2: + resolution: {integrity: sha512-B5znKqRmKROAN4oHWQ50W/qisVjA9GXh2WMsVKdFVp4DxWmcrOsweqgUOUVsv5th96kwaZlokU6SlV4J3gak1w==} engines: {node: '>=12'} - d3-fetch@3.0.1: - resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + d3-fetch@3.0.2: + resolution: {integrity: sha512-1wGF62bgjMRbF6mqbD+6rRWBL2hwWVYQjFO2UP3Wm1nIAvJZKaQxXM5caVY7athoCa8wIq9lCf7g44lPWFk50g==} engines: {node: '>=12'} - d3-force@3.0.0: - resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + d3-force@3.0.1: + resolution: {integrity: sha512-kAaaHLFebBYwgi5cYBXAI8vKrQFMCD2MEswj2QuPKKbdU1wYLc8WXtS7O8F/b6POCIe3gJjY6hkDstHi1yMETQ==} engines: {node: '>=12'} - d3-format@3.1.2: - resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} + d3-format@3.1.3: + resolution: {integrity: sha512-+F+/49swqmGuQJmSKnVMIDH/QkEFV5li9QRj0xm/KhyAUBv099O5PrvpQFxBp24PYph17Mnvt9mjKQV0ii0nMA==} engines: {node: '>=12'} - d3-geo@3.1.1: - resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + d3-geo@3.1.2: + resolution: {integrity: sha512-5R8ZgDQorIxmauv7R6gpE/ndz+Z0qAZssigq0aXFdvPHdY41RqtW02jrRUQAL724NdPABYXo1+gQEGBBr7uKNg==} engines: {node: '>=12'} - d3-hierarchy@3.1.2: - resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + d3-hierarchy@3.1.3: + resolution: {integrity: sha512-GRajN5ZcnEwYFWqqdzhG1qJ3+fDg6WWzk47TJg7ePY7yvYAgRfD2r1mUx+wviBOWuCwamCUzjwMSdato43jbGA==} engines: {node: '>=12'} - d3-interpolate@3.0.1: - resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + d3-interpolate@3.0.2: + resolution: {integrity: sha512-IRzGU62DtxhvsnSTWMQIdnoZ6gA+BCWwBon1EJI6SjoN595799b6z/QRBzXfFhE8iupUPp3042yBNo0STPqnzQ==} 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==} + d3-path@3.1.1: + resolution: {integrity: sha512-jsbgV8zIT38ReB9O7X7gcLndTQRONSqNNd+oGIaTBdUug4r5jFmp0N6RY9R5GWbdUDucn0qoTGyfjapT4tDhcg==} engines: {node: '>=12'} - d3-polygon@3.0.1: - resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + d3-polygon@3.0.2: + resolution: {integrity: sha512-WAUvPudGU1Dn4mDPfb6+JnnbeVEV53hG/BoT+bxts6AkZsOpTEiV1jHYX+2vtwCICNFG9Wxv8QS+eW1zE/Dwfg==} engines: {node: '>=12'} - d3-quadtree@3.0.1: - resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + d3-quadtree@3.0.2: + resolution: {integrity: sha512-9Lu9mqJKRbIk0d6mKDjpvPURaPdwHVK5CYbcdd0/4vBgz4ldz/7TIOse3kNERsByGNfld58KEco507AztJWyTQ==} engines: {node: '>=12'} - d3-random@3.0.1: - resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + d3-random@3.0.2: + resolution: {integrity: sha512-PxJi9LNV+7mulaYO77nd+oGurXGL1fhedXjHnB3pWLUcqDnQtF4VASoqnQGHgoXLByVdv5QJ/2kfwkGn5HTS8g==} 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==} + d3-scale-chromatic@3.1.1: + resolution: {integrity: sha512-lA5gfN2yMvmChubmptnDiBfeGpHD7Yb1EbvCz0TZE0WHXhyR6W2allPuhKtzV5ILQRqeOdefF0qYtERReLUBDg==} engines: {node: '>=12'} - d3-scale@4.0.2: - resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + d3-scale@4.0.3: + resolution: {integrity: sha512-66cWobCNzcMvlfoaDHCxuIv9TBUWG1BLOWdv9kHHFuCr1JdqAWPvTmsaEYDD5NRMyWZ5+7u0GqiCDfMXMqh3hg==} engines: {node: '>=12'} - d3-selection@3.0.0: - resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + d3-selection@3.0.1: + resolution: {integrity: sha512-ODSf35vqCrlCfp7hrm0eZjvOosSXSYLjqvIlhMBV9q9VOx7EBJG6pc+uXBswEZNJgCGJ+qnKYcWutbZDIxe/Xg==} engines: {node: '>=12'} d3-shape@1.3.7: resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} - d3-shape@3.2.0: - resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + d3-shape@3.2.1: + resolution: {integrity: sha512-dm2o+lbKdzg9tY7GEag/dB9hcbodLfwkE/DkvqbELJXaMz0yKzWWhZqhbI7CKubukA7HnRyz0avdtvi7EPxPvw==} engines: {node: '>=12'} - d3-time-format@4.1.0: - resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + d3-time-format@4.1.1: + resolution: {integrity: sha512-22XaqjyCjpqgda20erhsOjGmC3vvYwTNYniKAd45W5UWLDF43moeOuV9qYpRqobIlsnK0UhnKZjUUJm3VgORUA==} engines: {node: '>=12'} - d3-time@3.1.0: - resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + d3-time@3.1.1: + resolution: {integrity: sha512-Ze7rjrhMzdeulh0/hjcfFj7XLAHOfowtEMfsoG6DU866HPynQNW7Wfen6hzXcqKTv8XzxvF6Hzr5XD6bMHr2ug==} engines: {node: '>=12'} - d3-timer@3.0.1: - resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + d3-timer@3.0.2: + resolution: {integrity: sha512-1Il1aliroVSErrv5aulRBxAY+7+DnaoLIWGd1C6SsBTWDeobWiP/V69vwb8vT6abR1kKwaNe1196pmaQ1fK90A==} engines: {node: '>=12'} - d3-transition@3.0.1: - resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + d3-transition@3.0.2: + resolution: {integrity: sha512-RcjCsdFgyFoDB+QXLC5m60ZkTN0k9zH+ovoLlTdJnDS1AbfbcuowiM4pCKSTOclNibS4f4J4cbv2m7O7y8NTOQ==} engines: {node: '>=12'} peerDependencies: d3-selection: 2 - 3 - d3-zoom@3.0.0: - resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + d3-zoom@3.0.1: + resolution: {integrity: sha512-kfjD3BDQu/FOatpZ6JdMSyIoDwTxIpI29ySTI2J5ZlDaH1WbuJGQJ2Q9oJkWTEZEW98j6idezoomSD3Cn2zwiw==} engines: {node: '>=12'} - d3@7.9.0: - resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + d3@7.9.2: + resolution: {integrity: sha512-ZKb/mONPVKzaO5UlcWcwN8bS4ezvQaYu+bsou+XgNABdGC800kwH651ADTbbTxMPHW13UlvbQafdmJQDk1w7Mg==} engines: {node: '>=12'} dagre-d3-es@7.0.14: @@ -1271,8 +1271,8 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} - elkjs@0.9.3: - resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} + elkjs@0.12.1: + resolution: {integrity: sha512-IhMYKHE4S2vtx0QrhBP3lYOIKDeIiJXBrdq9MGYkuB8ZHqhrBnHNfSUndjXFewrX1CPK8chwq+2NA0K0hliYuw==} es-abstract-get@1.0.0: resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==} @@ -1306,8 +1306,8 @@ packages: resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} engines: {node: '>= 0.4'} - es-toolkit@1.53.1: - resolution: {integrity: sha512-VhMc6IXmexu8iYFfL2aaAww6IvJTdHlqBLruLoEUs33YD4IcP5DdZcLOybMsMmmLsiy1c8PsiLsrM0DdIuuRUA==} + es-toolkit@1.53.2: + resolution: {integrity: sha512-iUqZ+NlwH4jUgRmXZUxFBsV/9762TQEa1O4IXLFBmDEjVHScBytKuseX23I0+v9ShZ5MYxEx6WKNzm6IPnex8g==} esbuild@0.28.2: resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} @@ -1486,12 +1486,12 @@ packages: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} - glob@13.0.6: - resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + glob@13.0.7: + resolution: {integrity: sha512-wfsFgXQ8A3SEI9XGf7Nl3Y9l7ffSrGh7SUCT7vU/2CzYPep9kjxAn1S40F9OPKxAMGCVl7HtNlJhrCJUeUq83g==} engines: {node: 18 || 20 || >=22} - globals@17.13.0: - resolution: {integrity: sha512-RwMTC61u7hrG3ZJMkZQOK4JLJrKS8QtoTii63EmWvFXHqycY9FObBJQCbsLxSO8kjKhWE5kV1GC+Vb1g3RI0Zg==} + globals@17.14.0: + resolution: {integrity: sha512-UtdkTVyAJePQv0J2M9Xe4L0ruNSDV314XiIJsADI2Zf40bcdAonE/D/OhAU8AT99oij9mhLByb+NvA3QWZYgCg==} engines: {node: '>=18'} globalthis@1.0.4: @@ -1592,8 +1592,8 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.17.0: - resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} + is-core-module@2.18.0: + resolution: {integrity: sha512-qyax9fgaKOEC4qK8WZn7Q4IcoZC9RC1O1fFxRcRTq/oMMkWT/uXpqpXa12kzWR409zAt1drYN9N9BO26UmBCmw==} engines: {node: '>= 0.4'} is-data-view@1.0.2: @@ -1746,8 +1746,8 @@ packages: mdn-data@2.37.2: resolution: {integrity: sha512-rz9YOBGItdSbe7HcSArUbhiAv4SB/4DKRYg96CSFS2CcIYMbUvBtZlzA1NCbk2AdgbmYwMqwNblLpR441lLeiQ==} - mermaid@12.2.0: - resolution: {integrity: sha512-w7nr/SFrLO7BaVTs3dQTvYSV6nYSBj0Yy9DjBhsIJtAcHqRzXSq4Pg32ujHZ/AdWsAMNEvvhbm5dt9E2tOiHzw==} + mermaid@12.3.0: + resolution: {integrity: sha512-4113TdXeLAsMruJ79OpFL5O8+LTFXhQqZ260rF3tgUmiNAtRm4Uume04I+65PRN6yZ69J4f8rVYWW8zRk65UYw==} engines: {node: '>=22.12.0'} minimatch@10.2.6: @@ -1849,8 +1849,8 @@ packages: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} - pdfjs-dist@6.4.299: - resolution: {integrity: sha512-AVl138zALtfaAPvADulE0PZThbYzCBS79nL4pOSL/6Sm/4AH5A21BD9VHt97OlCuzJuCpmeZtAtkinisF4Vb1g==} + pdfjs-dist@6.5.438: + resolution: {integrity: sha512-vg8Pw1x+AFKy4AMDvhuWl5cOYV8d698UoEANoFFhc79hqXDnZQqnOXoxw3HG907WHOg1JYOvLhP756boddFxpA==} engines: {node: '>=22.13.0 || >=24'} picocolors@1.1.1: @@ -1932,12 +1932,12 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + semver@6.3.2: + resolution: {integrity: sha512-GYrCADwpu6yV5OAvchkQ27Z5wwMxWAEMg5NNWjyHh/5DboFFqbdbvYNIvZouQpxXyeMPoTOh0vdPYKlf0ZswdQ==} hasBin: true - semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + semver@7.8.6: + resolution: {integrity: sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==} engines: {node: '>=10'} hasBin: true @@ -2101,10 +2101,6 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - uuid@14.0.3: - resolution: {integrity: sha512-Sc5u1VVln93y1Xnz4R+CunOZc7R9LUcTmhj7Rc7Eg3HVcf7rVn2FOoa812fe0W8p3jD7xeoGSYbfqCGGH2B6xw==} - hasBin: true - w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} @@ -2399,7 +2395,7 @@ snapshots: eslint: 10.14.0(supports-color@8.1.1) eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.2': {} + '@eslint-community/regexpp@4.12.3': {} '@eslint/config-array@0.23.5(supports-color@8.1.1)': dependencies: @@ -2750,7 +2746,7 @@ snapshots: '@typescript-eslint/eslint-plugin@8.72.1(@typescript-eslint/parser@8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0(supports-color@8.1.1))(supports-color@8.1.1))(@typescript/typescript6@6.0.2)(eslint@10.14.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/regexpp': 4.12.3 '@typescript-eslint/parser': 8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0(supports-color@8.1.1))(supports-color@8.1.1) '@typescript-eslint/scope-manager': 8.72.1 '@typescript-eslint/type-utils': 8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0(supports-color@8.1.1))(supports-color@8.1.1) @@ -2816,7 +2812,7 @@ snapshots: '@typescript-eslint/visitor-keys': 8.72.1 debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.6 - semver: 7.8.5 + semver: 7.8.6 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(@typescript/typescript6@6.0.2) typescript: '@typescript/typescript6@6.0.2' @@ -2905,8 +2901,8 @@ snapshots: '@upsetjs/venn.js@2.0.0': optionalDependencies: - d3-selection: 3.0.0 - d3-transition: 3.0.1(d3-selection@3.0.0) + d3-selection: 3.0.1 + d3-transition: 3.0.2(d3-selection@3.0.1) acorn-jsx@5.3.2(acorn@8.19.0): dependencies: @@ -3047,7 +3043,7 @@ snapshots: '@codemirror/state': 6.7.6 '@codemirror/view': 6.43.15 - commander@15.0.0: {} + commander@15.1.0: {} commander@7.2.0: {} @@ -3085,172 +3081,173 @@ snapshots: dependencies: internmap: 1.0.1 - d3-array@3.2.4: + d3-array@3.2.5: dependencies: internmap: 2.0.3 - d3-axis@3.0.0: {} + d3-axis@3.0.1: {} - d3-brush@3.0.0: + d3-brush@3.0.1: 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-dispatch: 3.0.2 + d3-drag: 3.0.1 + d3-interpolate: 3.0.2 + d3-selection: 3.0.1 + d3-transition: 3.0.2(d3-selection@3.0.1) - d3-chord@3.0.1: + d3-chord@3.0.2: dependencies: - d3-path: 3.1.0 + d3-path: 3.1.1 - d3-color@3.1.0: {} + d3-color@3.1.1: {} - d3-contour@4.0.2: + d3-contour@4.0.3: dependencies: - d3-array: 3.2.4 + d3-array: 3.2.5 - d3-delaunay@6.0.4: + d3-delaunay@6.0.6: dependencies: delaunator: 5.1.0 - d3-dispatch@3.0.1: {} + d3-dispatch@3.0.2: {} - d3-drag@3.0.0: + d3-drag@3.0.1: dependencies: - d3-dispatch: 3.0.1 - d3-selection: 3.0.0 + d3-dispatch: 3.0.2 + d3-selection: 3.0.1 - d3-dsv@3.0.1: + d3-dsv@3.0.2: dependencies: commander: 7.2.0 iconv-lite: 0.6.3 rw: 1.3.3 - d3-ease@3.0.1: {} + d3-ease@3.0.2: {} - d3-fetch@3.0.1: + d3-fetch@3.0.2: dependencies: - d3-dsv: 3.0.1 + d3-dsv: 3.0.2 - d3-force@3.0.0: + d3-force@3.0.1: dependencies: - d3-dispatch: 3.0.1 - d3-quadtree: 3.0.1 - d3-timer: 3.0.1 + d3-dispatch: 3.0.2 + d3-quadtree: 3.0.2 + d3-timer: 3.0.2 - d3-format@3.1.2: {} + d3-format@3.1.3: {} - d3-geo@3.1.1: + d3-geo@3.1.2: dependencies: - d3-array: 3.2.4 + d3-array: 3.2.5 - d3-hierarchy@3.1.2: {} + d3-hierarchy@3.1.3: {} - d3-interpolate@3.0.1: + d3-interpolate@3.0.2: dependencies: - d3-color: 3.1.0 + d3-color: 3.1.1 d3-path@1.0.9: {} - d3-path@3.1.0: {} + d3-path@3.1.1: {} - d3-polygon@3.0.1: {} + d3-polygon@3.0.2: {} - d3-quadtree@3.0.1: {} + d3-quadtree@3.0.2: {} - d3-random@3.0.1: {} + d3-random@3.0.2: {} d3-sankey@0.12.3: dependencies: d3-array: 2.12.1 d3-shape: 1.3.7 - d3-scale-chromatic@3.1.0: + d3-scale-chromatic@3.1.1: dependencies: - d3-color: 3.1.0 - d3-interpolate: 3.0.1 + d3-color: 3.1.1 + d3-interpolate: 3.0.2 + d3-scale: 4.0.3 - d3-scale@4.0.2: + d3-scale@4.0.3: dependencies: - d3-array: 3.2.4 - d3-format: 3.1.2 - d3-interpolate: 3.0.1 - d3-time: 3.1.0 - d3-time-format: 4.1.0 + d3-array: 3.2.5 + d3-format: 3.1.3 + d3-interpolate: 3.0.2 + d3-time: 3.1.1 + d3-time-format: 4.1.1 - d3-selection@3.0.0: {} + d3-selection@3.0.1: {} 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.2 - 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 + d3-shape@3.2.1: + dependencies: + d3-path: 3.1.1 + + d3-time-format@4.1.1: + dependencies: + d3-time: 3.1.1 + + d3-time@3.1.1: + dependencies: + d3-array: 3.2.5 + + d3-timer@3.0.2: {} + + d3-transition@3.0.2(d3-selection@3.0.1): + dependencies: + d3-color: 3.1.1 + d3-dispatch: 3.0.2 + d3-ease: 3.0.2 + d3-interpolate: 3.0.2 + d3-selection: 3.0.1 + d3-timer: 3.0.2 + + d3-zoom@3.0.1: + dependencies: + d3-dispatch: 3.0.2 + d3-drag: 3.0.1 + d3-interpolate: 3.0.2 + d3-selection: 3.0.1 + d3-transition: 3.0.2(d3-selection@3.0.1) + + d3@7.9.2: + dependencies: + d3-array: 3.2.5 + d3-axis: 3.0.1 + d3-brush: 3.0.1 + d3-chord: 3.0.2 + d3-color: 3.1.1 + d3-contour: 4.0.3 + d3-delaunay: 6.0.6 + d3-dispatch: 3.0.2 + d3-drag: 3.0.1 + d3-dsv: 3.0.2 + d3-ease: 3.0.2 + d3-fetch: 3.0.2 + d3-force: 3.0.1 + d3-format: 3.1.3 + d3-geo: 3.1.2 + d3-hierarchy: 3.1.3 + d3-interpolate: 3.0.2 + d3-path: 3.1.1 + d3-polygon: 3.0.2 + d3-quadtree: 3.0.2 + d3-random: 3.0.2 + d3-scale: 4.0.3 + d3-scale-chromatic: 3.1.1 + d3-selection: 3.0.1 + d3-shape: 3.2.1 + d3-time: 3.1.1 + d3-time-format: 4.1.1 + d3-timer: 3.0.2 + d3-transition: 3.0.2(d3-selection@3.0.1) + d3-zoom: 3.0.1 dagre-d3-es@7.0.14: dependencies: - d3: 7.9.0 + d3: 7.9.2 lodash-es: 4.18.1 data-view-buffer@1.0.2: @@ -3319,7 +3316,7 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 - elkjs@0.9.3: {} + elkjs@0.12.1: {} es-abstract-get@1.0.0: dependencies: @@ -3413,7 +3410,7 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 - es-toolkit@1.53.1: {} + es-toolkit@1.53.2: {} esbuild@0.28.2: optionalDependencies: @@ -3453,7 +3450,7 @@ snapshots: eslint-import-resolver-node@0.3.10(supports-color@8.1.1): dependencies: debug: 3.2.7(supports-color@8.1.1) - is-core-module: 2.17.0 + is-core-module: 2.18.0 resolve: 2.0.0-next.7 transitivePeerDependencies: - supports-color @@ -3481,13 +3478,13 @@ snapshots: eslint-import-resolver-node: 0.3.10(supports-color@8.1.1) eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0(supports-color@8.1.1))(supports-color@8.1.1))(eslint-import-resolver-node@0.3.10(supports-color@8.1.1))(eslint@10.14.0(supports-color@8.1.1))(supports-color@8.1.1) hasown: 2.0.4 - is-core-module: 2.17.0 + is-core-module: 2.18.0 is-glob: 4.0.3 minimatch: 3.1.5 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 - semver: 6.3.1 + semver: 6.3.2 string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: @@ -3520,7 +3517,7 @@ snapshots: eslint@10.14.0(supports-color@8.1.1): dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.14.0(supports-color@8.1.1)) - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/regexpp': 4.12.3 '@eslint/config-array': 0.23.5(supports-color@8.1.1) '@eslint/config-helpers': 0.7.0 '@eslint/core': 1.2.1 @@ -3651,13 +3648,13 @@ snapshots: dependencies: is-glob: 4.0.3 - glob@13.0.6: + glob@13.0.7: dependencies: minimatch: 10.2.6 minipass: 7.1.3 path-scurry: 2.0.2 - globals@17.13.0: {} + globals@17.14.0: {} globalthis@1.0.4: dependencies: @@ -3745,7 +3742,7 @@ snapshots: is-callable@1.2.7: {} - is-core-module@2.17.0: + is-core-module@2.18.0: dependencies: hasown: 2.0.4 @@ -3852,7 +3849,7 @@ snapshots: katex@0.18.10: dependencies: - commander: 15.0.0 + commander: 15.1.0 keyv@5.6.0: dependencies: @@ -3887,7 +3884,7 @@ snapshots: mdn-data@2.37.2: {} - mermaid@12.2.0: + mermaid@12.3.0: dependencies: '@braintree/sanitize-url': 7.1.2 '@iconify/utils': 3.1.7 @@ -3898,20 +3895,19 @@ snapshots: cytoscape: 3.34.4 cytoscape-cose-bilkent: 4.1.0(cytoscape@3.34.4) cytoscape-fcose: 2.2.0(cytoscape@3.34.4) - d3: 7.9.0 + d3: 7.9.2 d3-sankey: 0.12.3 dagre-d3-es: 7.0.14 dayjs: 1.11.23 dompurify: 3.4.17 - elkjs: 0.9.3 - es-toolkit: 1.53.1 + elkjs: 0.12.1 + es-toolkit: 1.53.2 katex: 0.18.10 khroma: 2.1.0 marked: 16.4.2 roughjs: 4.6.6 stylis: 4.4.0 ts-dedent: 2.3.0 - uuid: 14.0.3 minimatch@10.2.6: dependencies: @@ -3932,7 +3928,7 @@ snapshots: debug: 4.4.3(supports-color@8.1.1) diff: 9.0.0 find-up-simple: 1.0.1 - glob: 13.0.6 + glob: 13.0.7 is-path-inside: 4.0.0 is-unicode-supported: 0.1.0 js-yaml: 5.5.0 @@ -3953,7 +3949,7 @@ snapshots: array.prototype.flatmap: 1.3.3 es-errors: 1.3.0 object.entries: 1.1.9 - semver: 6.3.1 + semver: 6.3.2 npm-check-updates@23.1.1: {} @@ -4036,7 +4032,7 @@ snapshots: lru-cache: 11.5.3 minipass: 7.1.3 - pdfjs-dist@6.4.299: + pdfjs-dist@6.5.438: optionalDependencies: '@napi-rs/canvas': 1.1.0 @@ -4092,7 +4088,7 @@ snapshots: resolve@2.0.0-next.7: dependencies: es-errors: 1.3.0 - is-core-module: 2.17.0 + is-core-module: 2.18.0 node-exports-info: 1.6.2 object-keys: 1.1.1 path-parse: 1.0.7 @@ -4130,9 +4126,9 @@ snapshots: safer-buffer@2.1.2: {} - semver@6.3.1: {} + semver@6.3.2: {} - semver@7.8.5: {} + semver@7.8.6: {} serialize-javascript@7.1.4: {} @@ -4351,8 +4347,6 @@ snapshots: dependencies: punycode: 2.3.1 - uuid@14.0.3: {} - w3c-keyname@2.2.8: {} which-boxed-primitive@1.1.1: diff --git a/dist-workspace.toml b/dist-workspace.toml index 7667dabc..d6d5707a 100644 --- a/dist-workspace.toml +++ b/dist-workspace.toml @@ -28,18 +28,13 @@ members = ["cargo:."] # Extra static files to include in each App (path relative to this Cargo.toml's dir) include = ["client/static", "server/hashLocations.json", "server/log4rs.yml"] # The preferred dist version to use in CI (Cargo.toml SemVer syntax) -cargo-dist-version = "0.33.1" +cargo-dist-version = "0.34.0" # CI backends to support ci = "github" # The installers to generate for each app installers = [] # Target platforms to build apps for (Rust target-triple syntax) -targets = [ - "aarch64-apple-darwin", - "x86_64-apple-darwin", - "x86_64-unknown-linux-gnu", - "x86_64-pc-windows-msvc", -] +targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"] # Skip checking whether the specified configuration files are up to date allow-dirty = ["ci"] license-files = ["LICENSE.md"] diff --git a/extensions/VSCode/package.json b/extensions/VSCode/package.json index bc730499..1945323d 100644 --- a/extensions/VSCode/package.json +++ b/extensions/VSCode/package.json @@ -41,7 +41,7 @@ "type": "git", "url": "https://github.com/bjones1/CodeChat_Editor" }, - "version": "0.3.2", + "version": "0.3.3", "activationEvents": [ "onCommand:extension.codeChatEditorActivate", "onCommand:extension.codeChatEditorDeactivate", @@ -118,7 +118,7 @@ "@emnapi/core": "^1.11.3", "@emnapi/runtime": "^1.11.3", "@eslint/js": "^10.0.1", - "@napi-rs/cli": "^3.10.9", + "@napi-rs/cli": "^3.10.12", "@tybys/wasm-util": "^0.10.4", "@types/escape-html": "^1.0.4", "@types/node": "^26.6.6", @@ -140,7 +140,7 @@ "typescript-eslint": "^8.72.1" }, "optionalDependencies": { - "bufferutil": "^4.1.0" + "bufferutil": "^4.2.0" }, "scripts": { "compile": "cargo run --manifest-path=../../builder/Cargo.toml ext-build", diff --git a/extensions/VSCode/pnpm-lock.yaml b/extensions/VSCode/pnpm-lock.yaml index 5c7ccc9c..a97b9dfc 100644 --- a/extensions/VSCode/pnpm-lock.yaml +++ b/extensions/VSCode/pnpm-lock.yaml @@ -22,8 +22,8 @@ importers: specifier: ^10.0.1 version: 10.0.1(eslint@10.14.0) '@napi-rs/cli': - specifier: ^3.10.9 - version: 3.10.9(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.6.6) + specifier: ^3.10.12 + version: 3.10.12(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.6.6) '@tybys/wasm-util': specifier: ^0.10.4 version: 0.10.4 @@ -83,8 +83,8 @@ importers: version: 8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0) optionalDependencies: bufferutil: - specifier: ^4.1.0 - version: 4.1.0 + specifier: ^4.2.0 + version: 4.2.0 packages: @@ -96,16 +96,16 @@ packages: resolution: {integrity: sha512-IUZydyTUkDnYdstOW9pFOOUQlBjAepK5teihDE3x6yxsPJs/hsAaaYpeGxdxrgtOiJbBKSjKW7MDk7AEhb4LRg==} engines: {node: '>=22.0.0'} - '@azure/core-client@1.11.1': - resolution: {integrity: sha512-2QygG2F76ZpMP2eMztiJvAiFMu71M9rDeU7vO/QKg5Css7MgM4frUOslFjhVjRhbGaCNPtz/S8M6y46/fFKVuQ==} + '@azure/core-client@1.11.2': + resolution: {integrity: sha512-ajuIU1aMoTs/ERYrKnIqQrV5Vz3RL8mwDC5RdedIXUvR7pi6cWzeYmt0LfNz6+W91CuCO4WJG0zA6+PhU1X+hw==} engines: {node: '>=22.0.0'} '@azure/core-process@1.0.0': resolution: {integrity: sha512-/shnJ+ooO8WPxDhPEeI/2oRQuubn16gZ6CvlbpWbEswZfzwI9tI/sMAHmF3x1LuQ9yZYXfLW3TjzGMLEC5blKg==} engines: {node: '>=22.0.0'} - '@azure/core-rest-pipeline@1.25.0': - resolution: {integrity: sha512-bMs8ekJLjX8wPV+9IPBges1SLPyuDtE9g5gLDWOpxzKcoOFQnpLGkbcT1tdw3FaAmDS1gnPmMmJ6y/T5B96kIA==} + '@azure/core-rest-pipeline@1.25.1': + resolution: {integrity: sha512-fTIA3CAm/cdODqiXkO6jYOIkU2Ylld7vq65KGc70gTwl12sLQsC8v7I5t6tp2N2CfUONzZBXyeFw7KEu6Ks2zg==} engines: {node: '>=22.0.0'} '@azure/core-tracing@1.4.0': @@ -124,16 +124,16 @@ packages: resolution: {integrity: sha512-rbAE25KUfjU/s3XHUdJgceoCP5dEOpMx85J04kF+QMdta73XkuG9JGHHinch+XIoKpBdqljin+KqURpJriSzLA==} engines: {node: '>=22.0.0'} - '@azure/msal-browser@5.27.0': - resolution: {integrity: sha512-i2CKKyuCuOZEBZJiAoFK/viYZAP6CRaqqlkeHl3ViteDHOUE/tkI/Slq1cdGnwhkIB+k1OE0g00QGl9O0gAFNQ==} + '@azure/msal-browser@5.29.0': + resolution: {integrity: sha512-Ko/Ovw6h+Gu33mp8f0FUyddr/KDWzbGzcgR8HKZaT4wgTYljLPKJP1rcDu0RHj7pkd4CR2hCHK51XFzgvq/Q5Q==} engines: {node: '>=0.8.0'} - '@azure/msal-common@16.15.0': - resolution: {integrity: sha512-lwdLb1B9Q5nEhPLVIKe78XH5wFMN15fCiDkY7ylPDSWZuWcD93G3jpJajrKhO3CQld8SLKz0sHiOi24mxdvtsg==} + '@azure/msal-common@16.16.1': + resolution: {integrity: sha512-dSKdL9h/iercb4GumsKFh+wVvLe1ohuDPiviklgnQVHnY2FYNUlbQJ3E1Qd37vkof9CfraK9BQpCW1hoOg0znQ==} engines: {node: '>=0.8.0'} - '@azure/msal-node@7.1.2': - resolution: {integrity: sha512-52hKQLGpEQzwNufIXG1SPVU+wQ3RIe7Rp2+g+VdAmZojCAZ6yCdGEffzQEQ6RnBZGBEs40nl14rWBmfJpCoHsg==} + '@azure/msal-node@7.2.1': + resolution: {integrity: sha512-6mntsfCNq7H1eAPSZik74jT3C5at4nRqiVk7OC+D5Hy3Pe3s76uwE4+J0xvDvlVPmoX2kasf3mSwUmzeq9rW/A==} engines: {node: '>=20'} '@cacheable/memory@2.2.0': @@ -145,33 +145,24 @@ packages: '@dual-bundle/import-meta-resolve@4.2.1': resolution: {integrity: sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==} - '@emnapi/core@1.11.2': - resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} - '@emnapi/core@1.11.3': resolution: {integrity: sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==} - '@emnapi/core@1.9.2': - resolution: {integrity: sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==} - - '@emnapi/runtime@1.11.2': - resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + '@emnapi/core@2.0.0-beta.3': + resolution: {integrity: sha512-KA+gOBtbifRATmUa/Gpf5C2B2EJ0r4brHUT3XSgACeHREcuiObXH56xd+B3fFsEFbUT04VBEe6MuZiCtMp0tQg==} '@emnapi/runtime@1.11.3': resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} - '@emnapi/runtime@1.9.2': - resolution: {integrity: sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==} - - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@emnapi/runtime@2.0.0-beta.3': + resolution: {integrity: sha512-ayb/PyyLzpwRyFVxeC0uoEHu59QlB1iWGcGsOpXQcaB/Dc+uGfBmNmpCHp3HmTT0t8lSsMmg3j7+tdJW/TlHjQ==} '@emnapi/wasi-threads@1.2.3': resolution: {integrity: sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==} + '@emnapi/wasi-threads@2.2.0': + resolution: {integrity: sha512-JP7OYH38Q7+pyTAe14raZHLQIK7BDKbdwji+Xi3pcd/6QkJYQH3SX4wu6EplGrGJWRepoNzedfm0G3B9Z4e9Rw==} + '@esbuild/aix-ppc64@0.28.2': resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} engines: {node: '>=18'} @@ -334,8 +325,8 @@ packages: peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + '@eslint-community/regexpp@4.12.3': + resolution: {integrity: sha512-R76UKbvsqI68DJJVTVyqFKqU98CN4+B+acxNfEA2IFarSzP0SjtKf/3+fFiXzTyv5Fj3PxLkGHe2wnVWWMxobQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} '@eslint/config-array@0.23.5': @@ -530,14 +521,14 @@ packages: '@keyv/serialize@1.1.1': resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} - '@napi-rs/cli@3.10.9': - resolution: {integrity: sha512-RpzJrTDlSxUi2Deo+dh4bmDTKklAVe295aSQjZspwbZyUBG7twbXbiKskL2w/bL4kNg3DdkrwbI/iQwI9kgQaQ==} + '@napi-rs/cli@3.10.12': + resolution: {integrity: sha512-8QDEW10Ld/uAemSP9g5WFIcmKh7I6PMA78ttc2UtZb+6cyAsX7RkVt2H5B658j7504R2JRE6JHs+b0WERHc+4w==} engines: {node: ^20.17.0 || ^22.13.0 || >= 23.5.0} hasBin: true peerDependencies: - '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 - '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 - emnapi: ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/core': ^1.7.1 || ^2.0.0-beta.2 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-beta.2 + emnapi: ^1.7.1 || ^2.0.0-beta.2 peerDependenciesMeta: '@emnapi/core': optional: true @@ -546,19 +537,19 @@ packages: emnapi: optional: true - '@napi-rs/cross-toolchain@1.0.3': - resolution: {integrity: sha512-ENPfLe4937bsKVTDA6zdABx4pq9w0tHqRrJHyaGxgaPq03a2Bd1unD5XSKjXJjebsABJ+MjAv1A2OvCgK9yehg==} + '@napi-rs/cross-toolchain@1.0.5': + resolution: {integrity: sha512-UhzMXkaW8xc1ekwDeahmezVU0BEeK68VvkpgmdDPcJPhGVdHrAF/xQTD8lpyMEkFat0w2vBMmklpoFtzNCUneQ==} peerDependencies: - '@napi-rs/cross-toolchain-arm64-target-aarch64': ^1.0.3 - '@napi-rs/cross-toolchain-arm64-target-armv7': ^1.0.3 - '@napi-rs/cross-toolchain-arm64-target-ppc64le': ^1.0.3 - '@napi-rs/cross-toolchain-arm64-target-s390x': ^1.0.3 - '@napi-rs/cross-toolchain-arm64-target-x86_64': ^1.0.3 - '@napi-rs/cross-toolchain-x64-target-aarch64': ^1.0.3 - '@napi-rs/cross-toolchain-x64-target-armv7': ^1.0.3 - '@napi-rs/cross-toolchain-x64-target-ppc64le': ^1.0.3 - '@napi-rs/cross-toolchain-x64-target-s390x': ^1.0.3 - '@napi-rs/cross-toolchain-x64-target-x86_64': ^1.0.3 + '@napi-rs/cross-toolchain-arm64-target-aarch64': ^1.0.5 + '@napi-rs/cross-toolchain-arm64-target-armv7': ^1.0.5 + '@napi-rs/cross-toolchain-arm64-target-ppc64le': ^1.0.5 + '@napi-rs/cross-toolchain-arm64-target-s390x': ^1.0.5 + '@napi-rs/cross-toolchain-arm64-target-x86_64': ^1.0.5 + '@napi-rs/cross-toolchain-x64-target-aarch64': ^1.0.5 + '@napi-rs/cross-toolchain-x64-target-armv7': ^1.0.5 + '@napi-rs/cross-toolchain-x64-target-ppc64le': ^1.0.5 + '@napi-rs/cross-toolchain-x64-target-s390x': ^1.0.5 + '@napi-rs/cross-toolchain-x64-target-x86_64': ^1.0.5 peerDependenciesMeta: '@napi-rs/cross-toolchain-arm64-target-aarch64': optional: true @@ -662,313 +653,313 @@ packages: resolution: {integrity: sha512-WrOw/bcXm0f9qHkumlT1QlArXSTWqaY9sunsDpOk+yCCorCKMxvWT/a3xko4EYHVdeZoh00yI2TydXn6eyICDA==} engines: {node: '>= 10'} - '@napi-rs/lzma-android-arm-eabi@1.5.1': - resolution: {integrity: sha512-sahBe4ko2Z69NPTddaX6ZgbQZu9SDoITxw1S3dWl1gAGynZG34qHHCT8UaUMFxf3h3zMhCJjEzz4basaBxiTuQ==} + '@napi-rs/lzma-android-arm-eabi@1.5.3': + resolution: {integrity: sha512-Jo8Ej9sTXZO+vHVllHPYxcHVoW4dQe30eLx7wk3H786vv2zy/qIIi5KoO6WhK/VsSBhAb13xbIa/vc4maUgp8Q==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [arm] os: [android] - '@napi-rs/lzma-android-arm64@1.5.1': - resolution: {integrity: sha512-7tkQAJJuBHxAxiEBNFgSTpvrtGpbwZYYJUSOmGEK3OfbdbNeoT2rdBxpM/gY1s+itEVbtOSlpaRPPG19MnwOzA==} + '@napi-rs/lzma-android-arm64@1.5.3': + resolution: {integrity: sha512-BUEMluJxOJ/9WkZH/IFyyi3viNQGEByodAHDbmJ/k7mVhabGIxjYBea3MmnyTZoIoqZs/ftAKH7jhVCIj+k6mw==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [arm64] os: [android] - '@napi-rs/lzma-darwin-arm64@1.5.1': - resolution: {integrity: sha512-XWX8gtF+GHGk3nH3Wm3QUZNcxw9QHsFVZz3MzVLhWWHhceede1J4/vD+3dj3E1iKB9G6mualaZxOoD08R3E+7g==} + '@napi-rs/lzma-darwin-arm64@1.5.3': + resolution: {integrity: sha512-ea46AUzmoGqWnrDP8JNea14TCiVMmxWtaD/d5YjRgh1KbL3YfZ9O2BZzfF7DAF+yrVuAQqS52rHveysjnzYlJA==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [arm64] os: [darwin] - '@napi-rs/lzma-darwin-x64@1.5.1': - resolution: {integrity: sha512-CfsqUpMTI1z8enrA/b+GcHM6YDI8D0kqCiqPYEnst4rbOABQ9KZ92ybTTNnlnZ7A017WoMZKUEWc36KXDwi0xg==} + '@napi-rs/lzma-darwin-x64@1.5.3': + resolution: {integrity: sha512-/vz8UpAe/9fV7JiTrT+lAV9Xk9bK4F28u8JRDNIYdGaT7lXP0r/e7YjDvBuJZ9bJtStW4nn/08q5Q7yfFmsF1Q==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [x64] os: [darwin] - '@napi-rs/lzma-freebsd-x64@1.5.1': - resolution: {integrity: sha512-bTyNfg90FXIgE61U7l14aMmVOqRQ6AyP5JMT3jmCStaZI18apLNPdzZ8i7yqxZfKvRMVfPjE2brXIw27c+RRgA==} + '@napi-rs/lzma-freebsd-x64@1.5.3': + resolution: {integrity: sha512-gAxemzm8Zk1OaMXihd0L8zeAb/P+71NqhrYnrPVweW3cTXg7XACC+zXQsvENAvHhkroeHCfaMmFupRwfHi+u7A==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [x64] os: [freebsd] - '@napi-rs/lzma-linux-arm-gnueabihf@1.5.1': - resolution: {integrity: sha512-vNE+D8nrw+eOkBsdKCsmDhowDV3pIMKXEhedvXfbgrWbrO7GlZJH+RXL+X+RYLxGwi8Ym61ZMt15sIOnNmh9Sw==} + '@napi-rs/lzma-linux-arm-gnueabihf@1.5.3': + resolution: {integrity: sha512-T7ZvCSEAKGoYSw7vIwdKgk1ZaYl8V1JLTgWSlGhnYBau23R9qZP79ONiF7FTosXnvR8G9RLe9peVuVGS5GI7ig==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [arm] os: [linux] - '@napi-rs/lzma-linux-arm64-gnu@1.5.1': - resolution: {integrity: sha512-csUem4WgoKGTprv/pOPm9UIWbb+hrfUwYXefpTHPAEGVFLl5behEFabisJ7FtihCa3yG2Efcl+yw25rlhhrIYw==} + '@napi-rs/lzma-linux-arm64-gnu@1.5.3': + resolution: {integrity: sha512-fEfgGb/y8jo2X57cTtMQ62XSD57rxDbpSbT38TSq0gSMKg6A/zq3oOxZLRfoCuZkL3cDtuZMi4fAuo6xIkP5eQ==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [arm64] os: [linux] libc: [glibc] - '@napi-rs/lzma-linux-arm64-musl@1.5.1': - resolution: {integrity: sha512-kB/xhlVN1eLvVmDJSKZEjp5Gg2xDYexNrB5jwpSMbOkeGS6N9AasByPBg5VqCpMYC+zZi7DM458DRhtWYhqXTQ==} + '@napi-rs/lzma-linux-arm64-musl@1.5.3': + resolution: {integrity: sha512-Phe10HwfNrtM7U2XsVLhJGePWOgx0BVW2/EWUBq1hoPkmKuUTjbrFj8y4XSTGS5eHMWABUtehnkbX+MPnN5sKg==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [arm64] os: [linux] libc: [musl] - '@napi-rs/lzma-linux-ppc64-gnu@1.5.1': - resolution: {integrity: sha512-s28RW0W1yBWQc1nbPdF7tp14koqslY3ZWLVI8uaanX292Dc6ezd4NPVwxEoCNBVON/oD7BmUbWGtyFvmm7dQ5A==} + '@napi-rs/lzma-linux-ppc64-gnu@1.5.3': + resolution: {integrity: sha512-rhuUE76jYbXZaR5oXAWqvfXzxoZKaCFM1nTH3yrdmz2Jtog5mnFcmyJ9WjDFmUgzQo062p1WfXWm3FA8SJOwaA==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [ppc64] os: [linux] libc: [glibc] - '@napi-rs/lzma-linux-riscv64-gnu@1.5.1': - resolution: {integrity: sha512-+lGNwYlIN14YPMTNvYtIJJqHFevDTd6Juw/1NmXbWx/iRd/LLrjhlM/yluMX6pxs6NkOGsuuEXJJrbbEUS59OQ==} + '@napi-rs/lzma-linux-riscv64-gnu@1.5.3': + resolution: {integrity: sha512-ogeKmHMV80J1uGYu5Lg4XVacyQxv9wapsEMEKH6beFtouIpo5wZMod5/zGLNHA+sg0/9HIAQbm/bVFJ5flkiQQ==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [riscv64] os: [linux] libc: [glibc] - '@napi-rs/lzma-linux-s390x-gnu@1.5.1': - resolution: {integrity: sha512-PB44FFWWFrLeQowhcep1hPD1YcLqKlnnY60RMU74qrxTlr4YGEyzeMItJqh2uivBfv9kQScOF/B0J9+Vab/oyw==} + '@napi-rs/lzma-linux-s390x-gnu@1.5.3': + resolution: {integrity: sha512-FvFzkI1zzVUqpX21UQdLZ0efTPxDolaCH1bqIp6k7hMTtx0RNwHJgcrsbGXQisAJ8uLWKRKncwNVL8MzcBVxUg==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [s390x] os: [linux] libc: [glibc] - '@napi-rs/lzma-linux-x64-gnu@1.5.1': - resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} + '@napi-rs/lzma-linux-x64-gnu@1.5.3': + resolution: {integrity: sha512-cqF0sRTngwVgnH0y7OV/5zWKWZomMYY71t3gzjtmJou4oPoWQHjxmO1Jo5E3GqUg2bPk+Fp3DcRw1xLAeKs1cg==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [x64] os: [linux] libc: [glibc] - '@napi-rs/lzma-linux-x64-musl@1.5.1': - resolution: {integrity: sha512-I3nsYrWtrW9JpeCr+mkJIVDt0HY3m6qVUBs5vTtoIvJQxwqf1PBXSy5IS7T53ksQFH2kd2UX8rLxJ7B4WISpZg==} + '@napi-rs/lzma-linux-x64-musl@1.5.3': + resolution: {integrity: sha512-ZBMasmon/mQmwIKNCWDJagq/zq45vvDQzhSijJSBSIgyef8IRvoD9O4H2lq62Lrq3toHxhlMD2D85jwUVr4QQw==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [x64] os: [linux] libc: [musl] - '@napi-rs/lzma-wasm32-wasi@1.5.1': - resolution: {integrity: sha512-gy3wwPBa6+XEyA4fUzq6CClrXA1ajXjuVf5zbnHytJRgoHznj+mvpU3+co2fxXwqTCmIpn6KrzqH5bRDztBPhA==} + '@napi-rs/lzma-wasm32-wasi@1.5.3': + resolution: {integrity: sha512-gJ2YpVByn8xNbSCbOwQhCN9Jc2ZQY0ERx/K3XFDldbyiFXCphbEnciptp3bwqcp+WUJvIvpZxcKP1+6tcUEj1g==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [wasm32] - '@napi-rs/lzma-win32-arm64-msvc@1.5.1': - resolution: {integrity: sha512-dK+huOsHiyH6oJjij+cnjqFCakk2HgWmpI12Xm4pLUyPphe4ebYoJBgehaNAxprmjFqBQ7nL95YPVz9BHyqmPg==} + '@napi-rs/lzma-win32-arm64-msvc@1.5.3': + resolution: {integrity: sha512-oB9iJluslRc3bZ3upZ7ZD2tJfICX3tjTsqS8jUUWK+d7PpJei/oZ3YklBLNyczmLZ+JXHYZlBbotIeVCaoNGPw==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [arm64] os: [win32] - '@napi-rs/lzma-win32-ia32-msvc@1.5.1': - resolution: {integrity: sha512-dGE8L+0EQ+GyU9ap9InqB/t/PmPG/bLj918q7OsJ29FuTdn8fK4OX3U4IQZhylHIA+/dQ/SXJk5n4yfah2XVvA==} + '@napi-rs/lzma-win32-ia32-msvc@1.5.3': + resolution: {integrity: sha512-b5HxoRno1C9kS9I9pH9E7uYO9oMEQZ2RuOzAs8+PafoHzcHA5KMzSibNfA//seedILG1w22IS7YfrW4s0+4FvA==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [ia32] os: [win32] - '@napi-rs/lzma-win32-x64-msvc@1.5.1': - resolution: {integrity: sha512-EKW4t/iqdCT/xnd5t9oXLvVER/PMNAWXKqUAl3fgvUcOILeZIIht77/dVnfFcc9htA/DCBXC/6YQWdW+LusjFA==} + '@napi-rs/lzma-win32-x64-msvc@1.5.3': + resolution: {integrity: sha512-cPH8uIK0aaD9KZ0FTPBBPTIvncNHQ2Si3DNTP2rjPWyDRVV+syT2dWvlmkiklKgnRipXtx4eJ+tYQZhG30/+9w==} engines: {node: ^22.20 || ^24.12 || >=25} cpu: [x64] os: [win32] - '@napi-rs/lzma@1.5.1': - resolution: {integrity: sha512-sgOZ89+y8cDbY+3WbzR8CtIhCuFRWotZ9/2PjPVDJHz6np5KFTAev0DrwiyTJTgFsCRDhfGlbmhMgyhHbWdZ6g==} + '@napi-rs/lzma@1.5.3': + resolution: {integrity: sha512-QSIzELPyd2A7mcaDiJEWjwzApoAOWq9PVl9xYq+CxzIwstufv48s8aBgOUr0sgbjGmb15aYU88YKNaFaCaOuhQ==} engines: {node: ^22.20 || ^24.12 || >=25} - '@napi-rs/tar-android-arm-eabi@1.1.1': - resolution: {integrity: sha512-cAhnA10cSusAUbcE9HtjQY/tZ9BH/0w2sKtRcQc94TzIlnm7QSr1htJSd/PPrbWNPtrv1orXb2CkrHlVlbnlHA==} + '@napi-rs/tar-android-arm-eabi@1.1.3': + resolution: {integrity: sha512-WDzurP2WgSlMVi6X96kTJRS9Nu+EKxTQkbLzdrGhhkVptO3cwvbY53S/H6c43xIFsI0ZskmyTNmYiAvj2nfwSQ==} engines: {node: '>= 10'} cpu: [arm] os: [android] - '@napi-rs/tar-android-arm64@1.1.1': - resolution: {integrity: sha512-EslUWHCDBY/g5abTPBiHLsMaML4GagV0TXLm5WL9hAjx/DDtlxz9fegMb77RJ+f7nFLOIsUxF/3QWFvgOT0sMQ==} + '@napi-rs/tar-android-arm64@1.1.3': + resolution: {integrity: sha512-cVhQUzlHy/YY7tLqCPa3ibRQlocM8haPLW/ZR9FysI1JN/T9TDUiEhWl+SJIMDr+EvSQxyPwOYP45adtx6ZCXw==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@napi-rs/tar-darwin-arm64@1.1.1': - resolution: {integrity: sha512-+A42/6ES5G9CQ35BOwzwA+WBjLID28r2jNPgc0dteD2hhClIhng0mva7D2ujUlXBNmgNOsr1LHn3stA4uTf4NQ==} + '@napi-rs/tar-darwin-arm64@1.1.3': + resolution: {integrity: sha512-LOGjc5FwCjZdGNRVjXZr0ItdsweAfwmVCnLkQLpx9IovNHhLKzwCWAa2ePdN/e+bbsOXDoUc8MrAtY0IUVWKcA==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@napi-rs/tar-darwin-x64@1.1.1': - resolution: {integrity: sha512-RYtE8w1dkEvj8hSJCDV5Jw0Rz2i13fsM7u893zv5O9n/4Ad5GNsw/f4RQ7/0YGSFaenkVxqPFrjmEvUHlKzsrg==} + '@napi-rs/tar-darwin-x64@1.1.3': + resolution: {integrity: sha512-Lqk5gYf5mlrGTPrIZKaRfGOKvbrqLxXAGsHre2zHLIvsFxJH6lJpPB/YXIYEMMCeSrySiZAtRlA2rKPlNGxTHg==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@napi-rs/tar-freebsd-x64@1.1.1': - resolution: {integrity: sha512-rEepBvCJUwcuvUYkY83e8aot8RsR5Jcnal4PsG3tbWGKW1yAvcXhyMXf0fN6ZGpVRZFnB+FJqDyBxvsCPEXKhw==} + '@napi-rs/tar-freebsd-x64@1.1.3': + resolution: {integrity: sha512-HnrZ7YISLyPWwafzM3+xAlmgo3glb8L9jUvpVMBSVP4uo11/WXe+3GVFe9WywmXE047neDsWXYz6S4gXAX52Cw==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@napi-rs/tar-linux-arm-gnueabihf@1.1.1': - resolution: {integrity: sha512-an1bJdfyhI5FpZYyTQ20mrqwR+a676i8GkaYc4Uy12dH/a7TJIfrK6Qa2Gm46arZvxUvx56qxoRKXbpOjUPvwA==} + '@napi-rs/tar-linux-arm-gnueabihf@1.1.3': + resolution: {integrity: sha512-BLXGHslkW6jBInBuYVWMcmnlCqeWZOOWVZvn0Cr5bcMmPuq2Va18A7DOz6yYs/ebI1FnnasddbShXhLZAOHWfw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@napi-rs/tar-linux-arm64-gnu@1.1.1': - resolution: {integrity: sha512-w++Vtx36T2yHTKws7GVnmHHcUT1ybB59xLWSh9A8bwEpJVG4dG7Qub9mFe5cpcbfrJ+XP2mKKxC3oUJSunK3iQ==} + '@napi-rs/tar-linux-arm64-gnu@1.1.3': + resolution: {integrity: sha512-V7sdJPgYWx6msrpNO2v5OREbyEgk5eOJOF9rUpVzEA6Z4BWubFcElcQMyBkDgb8jOtor3b/z91Ep+aD4C2GHVw==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [glibc] - '@napi-rs/tar-linux-arm64-musl@1.1.1': - resolution: {integrity: sha512-Rh6UFhNtj3i4deJHOBINFIeRL0072mgbeyuK5rl1HokKnNoMKx8qKIZNEzBTTqpogMfDHWGvzyTQdnVxes5dpA==} + '@napi-rs/tar-linux-arm64-musl@1.1.3': + resolution: {integrity: sha512-wkkRDMI6+8duivzcvgoXJAfEAI0MFoRkjPq0fEMaBakK8E4xAePWjpLk4757ejQ0UwoV6aVFCgHJafySvuFXFg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] libc: [musl] - '@napi-rs/tar-linux-ppc64-gnu@1.1.1': - resolution: {integrity: sha512-Cp+AxFbv9zcyAXtnzQi0OzmgDnQgy2w9D4Ubr+iwzMtVgJcztzcEoCcCrN1k2ATdEB01LX2Vb49IaocGOZhC9Q==} + '@napi-rs/tar-linux-ppc64-gnu@1.1.3': + resolution: {integrity: sha512-1eaqPDSrBfmaDK7PHhOGwfm8S+Yg/0uOB5heY9b/B8vCm5+CmKt8Z2x4KfI39udz4kcwlMXAhDQrctRzGRravA==} engines: {node: '>= 10'} cpu: [ppc64] os: [linux] libc: [glibc] - '@napi-rs/tar-linux-s390x-gnu@1.1.1': - resolution: {integrity: sha512-ZyscC3SYKTBWyDRYjLOKAd5TyJ7q0KACRdQ8bWrb3rgrra1CCIJD66CsGTH6Dh0AVSdfLwZ8MfIIXU6+14BMjQ==} + '@napi-rs/tar-linux-s390x-gnu@1.1.3': + resolution: {integrity: sha512-o6qluAuWUZP9YUL3uzr7kBabbWyb/hVi7jlNU58snxZXgmtn+N3vbk67F67KD5LqJn8DQR3IgA13Sfu/v+IR3A==} engines: {node: '>= 10'} cpu: [s390x] os: [linux] libc: [glibc] - '@napi-rs/tar-linux-x64-gnu@1.1.1': - resolution: {integrity: sha512-LlIv+zg4fiOQge9LQX/ieBdRWE2fhVDjCTHxnunZkbugNmdhdelxWf1RpZb/6ZujWpNF4LPu4N/MW7ygg2oYAQ==} + '@napi-rs/tar-linux-x64-gnu@1.1.3': + resolution: {integrity: sha512-mt32bxTy7cSDVpca7T8Y3b9LgV8s/dBqGVZrZvIkVm2EFAyKe7rD0FjGgciw2BZNVmLGZCl1wIdRfzS45boFzg==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [glibc] - '@napi-rs/tar-linux-x64-musl@1.1.1': - resolution: {integrity: sha512-gZBeoKLjanOVj55qk4EMu13P2i9M0SuINmlGQkOxm1niIJofexzddHUYtqO5o/5QqtyL8lADmAcZplLILMLhHA==} + '@napi-rs/tar-linux-x64-musl@1.1.3': + resolution: {integrity: sha512-XbKOipWcorf08qf/KZ8MV1OwW9Wtgcg210yzONW0T9HTkgY1vRj5KzFuXoPLO/0H29GCO1xokY8HT4c6NDzCpA==} engines: {node: '>= 10'} cpu: [x64] os: [linux] libc: [musl] - '@napi-rs/tar-wasm32-wasi@1.1.1': - resolution: {integrity: sha512-rwtQ1Mdt/ft6g6I54fJzbUeLspl4yTwj6I3UJ6mitKnrN42soJkcDrdh3Y/FGvlpqZTad2YMQ96fGJl3EtAm2Q==} - engines: {node: '>=14.0.0'} + '@napi-rs/tar-wasm32-wasi@1.1.3': + resolution: {integrity: sha512-pUZYJ51H8sMB9vG1sT1aJVQqmoT4d7JmT1nER/pCsHtFQzk5aBvXuvj4G3Wo2BBCRr2eY+7zXFpJCtj50QuzeA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} cpu: [wasm32] - '@napi-rs/tar-win32-arm64-msvc@1.1.1': - resolution: {integrity: sha512-30PVp1AehRpfwxmv5wI4cg0yj3WmWBsZ+1QnLGnvEELu7Eu/+dhNU0nrmhI7VfPgLwSRK2eg9DQTB3tP7Wv9bA==} + '@napi-rs/tar-win32-arm64-msvc@1.1.3': + resolution: {integrity: sha512-KtAW+o86AZfMng8lC83pisb6Xe50NrbYpNa5ENOapWZBrLl3HU9+PxDQfoxoGTCvLTHU7aoiSzQntE8Ej9cYGg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@napi-rs/tar-win32-ia32-msvc@1.1.1': - resolution: {integrity: sha512-aI3/rmz+izUChiSeaPxcasAOxhf3FpJNuIHMXlxS/vpW+HIxUsSDR5+XV61PEG5DL4L/75iENVUxmSGM5l2yaw==} + '@napi-rs/tar-win32-ia32-msvc@1.1.3': + resolution: {integrity: sha512-A82IKQLi/ZIYgbeLmN+h/LU/H9O78CUAEffdH6PCLsQznX4oZwSvAIXmFxqU7QVk+zLkYQvD7Kau2sBDlCOcIw==} engines: {node: '>= 10'} cpu: [ia32] os: [win32] - '@napi-rs/tar-win32-x64-msvc@1.1.1': - resolution: {integrity: sha512-yJsB2IsrODQVLKbm2Fg1nHiVRbEj49mSPbj4x7JPZWJI0jGVPjohE2Sif0FBbx8OxsVoUODvS0BwksZZ8jl/OA==} + '@napi-rs/tar-win32-x64-msvc@1.1.3': + resolution: {integrity: sha512-Iq/zg92fzXEX7ajcjg2cnAf3YIVR6osfqd7OWucIEWg1NdtA2t2C4Eg8AiDgxHp9/ym+YQ+w5TMhAqJ5FCGo+A==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@napi-rs/tar@1.1.1': - resolution: {integrity: sha512-p6q2HhUc5vwH1CNwfOcrhLoxfgn8ust8Sqlfx+sA4VzAcp1cMbvbkl99tZZlDqOjCHgQNSiTfk/yWPjl/D42qA==} + '@napi-rs/tar@1.1.3': + resolution: {integrity: sha512-W1TENanv88k5OvB+TfkRnTc35ISN8vqvBqAxbWws64AToZKJjtay2yOw2QNVvJmX2SSkKM5JwmHzy96L8c53MQ==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@1.2.6': - resolution: {integrity: sha512-mRyDmEw9/fCDXCGfL1sbgIw/GUK0PVxRW4YwgPN61F3LQ+fSyoBFarJVzgGyhF6kRzEQZ0FejDqm4WLXSeqQmw==} + '@napi-rs/wasm-runtime@1.2.7': + resolution: {integrity: sha512-zJccwplOAbgfZju95IUHazLnx9RAPtPN2YGJXI6UbrgeaR9QfPjGrQL6ERkSAtnVCA4Q+83ApGyaX5zdpCaKkQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} peerDependencies: - '@emnapi/core': ^1.7.1 || 2.0.0-beta.2 - '@emnapi/runtime': ^1.7.1 || 2.0.0-beta.2 + '@emnapi/core': ^1.7.1 || 2.0.0-beta.2 || 2.0.0-beta.3 + '@emnapi/runtime': ^1.7.1 || 2.0.0-beta.2 || 2.0.0-beta.3 - '@napi-rs/wasm-tools-android-arm-eabi@1.1.0': - resolution: {integrity: sha512-p6J8PB59I8d/XItXB/go5JH6nKW+xIbpzaL43EBTV0hi7mrS/Z4gs+MsB04ZrlqZN29BdZV8fChRyasuXLhRaA==} + '@napi-rs/wasm-tools-android-arm-eabi@1.1.2': + resolution: {integrity: sha512-a+SYoe8acnmJsBCeJ23V9Gxp0rKHY7tm+mDCouOxaf4ELQuoVLPMso8t4ofIK3PpVLIEKY98YdS1cqJ5wLabNQ==} engines: {node: '>= 12.22.0'} cpu: [arm] os: [android] - '@napi-rs/wasm-tools-android-arm64@1.1.0': - resolution: {integrity: sha512-lWoKN3suypeBSCIRPIw+++sH9V2K6nQkhtdt1opu7XY3v9JwLs6Gw063HWRqkNjphlYpkd/Qy8XcfSPGbJj7nQ==} + '@napi-rs/wasm-tools-android-arm64@1.1.2': + resolution: {integrity: sha512-NP82W1n8Gtg9C5mO6Bv6TyTGWBuq/5yJtRC9btnjDb98XPK7GRzb/Pzdta+tojzyojnpbre2jYCbEx98y6QrWw==} engines: {node: '>= 12.22.0'} cpu: [arm64] os: [android] - '@napi-rs/wasm-tools-darwin-arm64@1.1.0': - resolution: {integrity: sha512-jfw5vyNDUf6oe0kP8lMveFN9U7cLk1cUosS7uMIfw/xmqmopYfKQ198DAx2g/6aEF7Tm+CqER2gpMpYKui30LA==} + '@napi-rs/wasm-tools-darwin-arm64@1.1.2': + resolution: {integrity: sha512-bROsO82JGuTgvK9UoqRT45i8MtfMvF5HQ0DCBlWU3sDywWJTWWITXA/GFUuTnLE1XU+02VIVAPYujmbLdCaosQ==} engines: {node: '>= 12.22.0'} cpu: [arm64] os: [darwin] - '@napi-rs/wasm-tools-darwin-x64@1.1.0': - resolution: {integrity: sha512-R+pjeudAB7BYdH1vKkOJM61Tfv5jB6uXkxmFscYd+KKpdUpWBlNG+s4hr0w4i1rMBM91VhIAETZn2pz+MDHK9A==} + '@napi-rs/wasm-tools-darwin-x64@1.1.2': + resolution: {integrity: sha512-uZ/0Z3Ru4DRhHALWyejYXQCbeyI60eYqOwBvdjSk51oMjLXMA6mfpc7ly3MaFGLcjV3mE9fBdNa9TXlsTHzQng==} engines: {node: '>= 12.22.0'} cpu: [x64] os: [darwin] - '@napi-rs/wasm-tools-freebsd-x64@1.1.0': - resolution: {integrity: sha512-hQJTe+aazrT++Vgm6I4lUd9099ItUCFYdd+aKg6Ys6nax6d/cZ1barDLTwA2lwOoVDsXMekJI/FOL6ZvVlIYBg==} + '@napi-rs/wasm-tools-freebsd-x64@1.1.2': + resolution: {integrity: sha512-6vcpEv4VC0uPTk6USmP7MRElqqbtEKs5jtdUApuTLCE7HrHkms9Qa/s8c/d2mUoywJ6EuzbAuY4vC2KWY6swCQ==} engines: {node: '>= 12.22.0'} cpu: [x64] os: [freebsd] - '@napi-rs/wasm-tools-linux-arm64-gnu@1.1.0': - resolution: {integrity: sha512-1TAXJxUHsWGar90k3W/MknavvBMwOWzjh7Q6Spxo8twRcWJbBD5Kow/Q2KhhDq5hxh2sKGDXn3uLc1tdtz4WUg==} + '@napi-rs/wasm-tools-linux-arm64-gnu@1.1.2': + resolution: {integrity: sha512-3/hLebdY3mgLx/RR3OBgJv0+mPge0/K0IzlTNRqv7sgGQPcKL3eYIfQfcPZu7DqCwBliJwnrrHJUTkOCRWGlew==} engines: {node: '>= 12.22.0'} cpu: [arm64] os: [linux] libc: [glibc] - '@napi-rs/wasm-tools-linux-arm64-musl@1.1.0': - resolution: {integrity: sha512-7rw3nlubTjNAVRH2LwphCxHy1b/N2/TerXocQ6XRn4Q+buaY1Z7P/hbdALy1i1ex2yfOU2Xcij7ib7ZLi/lKfw==} + '@napi-rs/wasm-tools-linux-arm64-musl@1.1.2': + resolution: {integrity: sha512-MJlyQuZqY2xzVezkwJY/JFVemFFMsbR9HyutG7jqlLjuGgTVHqj0gQzw40FVEl43EWnn/w6e8M5T/FNjkf3mpA==} engines: {node: '>= 12.22.0'} cpu: [arm64] os: [linux] libc: [musl] - '@napi-rs/wasm-tools-linux-x64-gnu@1.1.0': - resolution: {integrity: sha512-1sel0t9MRjI/tdT89M8Dd6gPfANeeFP24Xa46R11WeHNwhjsXXZh+xUk50uWCRTSGcaCy3ugm3AMK/lmHYQJkg==} + '@napi-rs/wasm-tools-linux-x64-gnu@1.1.2': + resolution: {integrity: sha512-G68ncazFlsRwXyflUncSu59p3Xfd5AUy79dIh01AeHgrEu8hMCj/g+63NUsaNjzgL8pwuB21rnA8hN0xtA3+Gw==} engines: {node: '>= 12.22.0'} cpu: [x64] os: [linux] libc: [glibc] - '@napi-rs/wasm-tools-linux-x64-musl@1.1.0': - resolution: {integrity: sha512-o2jH5AMfor4EKF2HII1LBnMQxoWu7+usPifTEY8Zk6e9OiSi4EJkAXf9v3ANlX7TI2V/cUEV34OEW7r10GiVIA==} + '@napi-rs/wasm-tools-linux-x64-musl@1.1.2': + resolution: {integrity: sha512-skm8hhSd/qxBwenE5msnMyRo58spnH5YQdWCgFgJXltiMqCcBMI7e3qcPt1Ir4tfkPn0kSKeliKS3bvw1yNxHA==} engines: {node: '>= 12.22.0'} cpu: [x64] os: [linux] libc: [musl] - '@napi-rs/wasm-tools-wasm32-wasi@1.1.0': - resolution: {integrity: sha512-s6YDtDR1UWrsqJPtaxf+JLYLceWVyn3l8OpQYElHkDhf3Qfz9R6Ba3S0OgznTBv38L5/TIHysQ9Q4yO73Z0csg==} - engines: {node: '>=14.0.0'} + '@napi-rs/wasm-tools-wasm32-wasi@1.1.2': + resolution: {integrity: sha512-ZLeQOPDsIlvRWro6zIHe77d8VPDAwvzCk5QLQcoHseEi0TtgjqVLn5/HxjqtNZVPdWgujpm02XVxq5Dc1f9o/Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} cpu: [wasm32] - '@napi-rs/wasm-tools-win32-arm64-msvc@1.1.0': - resolution: {integrity: sha512-x+NuxbG84VxU68tU8w7Rf5lSyq0l584M6dVlke5DTweHYFZoMyeqkpbwEq+qsyAX6ivfipK8xRsmFwamb5uDnA==} + '@napi-rs/wasm-tools-win32-arm64-msvc@1.1.2': + resolution: {integrity: sha512-ctoE1iYL2VVBc+cSyj3qIil1FIZ+T9EdraGxH/awZnCag3+bUjdXl/gIv59DmFLqb9DsH6cl0KYyF7EcRGXdXg==} engines: {node: '>= 12.22.0'} cpu: [arm64] os: [win32] - '@napi-rs/wasm-tools-win32-ia32-msvc@1.1.0': - resolution: {integrity: sha512-mdD96QDEp70SX67rXFTY6c725nVYeqEEjyDqzzbNh6u1APj7CI7IMNpMmvE75XbCRl4C2MHZVU4U6AWdAzvyQQ==} + '@napi-rs/wasm-tools-win32-ia32-msvc@1.1.2': + resolution: {integrity: sha512-2qLV0CacEbm/IxL/iPdABjayj67UUT1wOBbBcsylXsZd+ELxnzmYSS/PCAHQwAuANgnNMY6Y7F5CYx0SKAYL4Q==} engines: {node: '>= 12.22.0'} cpu: [ia32] os: [win32] - '@napi-rs/wasm-tools-win32-x64-msvc@1.1.0': - resolution: {integrity: sha512-bVVjuvhlyVX++3eJXfDR63cXdw1ay5QYac6iq0MKQw8wZARInTM+bXCtByDT4fzVFI3+7ZthYb/ERWRdBNIqgQ==} + '@napi-rs/wasm-tools-win32-x64-msvc@1.1.2': + resolution: {integrity: sha512-06DvdhcaUN29c62IE96/ZQcNykWNQAf9wWELyo4eLim3baSDw9OvdPHseLtfzs27cev2YyuvwaSuxAdYpD2LMw==} engines: {node: '>= 12.22.0'} cpu: [x64] os: [win32] - '@napi-rs/wasm-tools@1.1.0': - resolution: {integrity: sha512-VjHyKEqXAwYZK+HY7iJctYvRm3TFEbaQxeZwvAG1QRkoo1a39phMY8J6x9tUEqJI03W6MysB8F2jacI6wvcx+w==} + '@napi-rs/wasm-tools@1.1.2': + resolution: {integrity: sha512-VM6AVh5aYrUZtadC/ozmyx6lr1mE5RKqBXSrF6HkTrft9wFhHKD8hcKJ9v7QeA0H0QX5Og/7L21hILAICqFLww==} engines: {node: '>= 12.22.0'} '@octokit/auth-token@6.0.0': @@ -1266,8 +1257,8 @@ packages: resolution: {integrity: sha512-mbCddXd+jm7hfx7w2YU64/Av4/NqqeG3GoRZgxPcgoTxYjhrcfJRw9ULch71SS4G+Q3bOXFhRvPqjguN0Hyp5w==} hasBin: true - '@typespec/ts-http-runtime@0.3.9': - resolution: {integrity: sha512-edSdeAqkdxBVzA1yL1LrLCml1YjyCVvPMtMqJpbF+6K609tHe8V6sQUzFQSGcYNhcuhOceZtjvN32+mpIth30A==} + '@typespec/ts-http-runtime@0.3.10': + resolution: {integrity: sha512-vddvvtZ7sejSlCv+OIkn2ztjB1O31Fc2JsxI/YK725r3elXXlF/J3o3lbXJFRhoeWRWK1tjdZ+GTi6Fdtrp+EA==} engines: {node: '>=22.0.0'} '@vscode/vsce-sign-alpine-arm64@2.0.6': @@ -1333,9 +1324,9 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - agent-base@7.1.4: - resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} - engines: {node: '>= 14'} + agent-base@9.0.0: + resolution: {integrity: sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==} + engines: {node: '>= 20'} ajv@6.15.0: resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} @@ -1412,8 +1403,8 @@ packages: buffer-equal-constant-time@1.0.1: resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} - bufferutil@4.1.0: - resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} + bufferutil@4.2.0: + resolution: {integrity: sha512-gyy58jET9kst2IGyBKb96a4Y2bPGTHXGyCd0/1eqIV3hr1Sz3VxtA8n7bXh8fLIuE2K6Z0Upax5a5Msx+HU1IQ==} engines: {node: '>=6.14.2'} bundle-name@4.1.1: @@ -1540,8 +1531,8 @@ packages: resolution: {integrity: sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==} engines: {ecmascript: '>= es5', node: '>=4'} - entities@8.1.0: - resolution: {integrity: sha512-kxL7msIffSuh9aaFAMD7rxAIuTRMAHMeBtgHW2yUdWw732ZNh4MehkF2gdjvtdmikkaIP9bFDDJOPlsvm7avrA==} + entities@9.0.0: + resolution: {integrity: sha512-oJFNDJg3kTPwAD1cNn2+WmUq4wFoo09npc3Ydf1D7ED4smRiWrsKnaLxykrTWgyGEcusc87P5dxlAleol9kpkg==} engines: {node: '>=20.19.0'} es-abstract-get@1.0.0: @@ -1576,8 +1567,8 @@ packages: resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} engines: {node: '>= 0.4'} - es-toolkit@1.53.1: - resolution: {integrity: sha512-VhMc6IXmexu8iYFfL2aaAww6IvJTdHlqBLruLoEUs33YD4IcP5DdZcLOybMsMmmLsiy1c8PsiLsrM0DdIuuRUA==} + es-toolkit@1.53.2: + resolution: {integrity: sha512-iUqZ+NlwH4jUgRmXZUxFBsV/9762TQEa1O4IXLFBmDEjVHScBytKuseX23I0+v9ShZ5MYxEx6WKNzm6IPnex8g==} esbuild@0.28.2: resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} @@ -1832,13 +1823,13 @@ packages: resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} engines: {node: '>=10'} - http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} + http-proxy-agent@9.1.0: + resolution: {integrity: sha512-2NxoveTT58mjYT4n3RPTEfCZGLMbidoO8XEieXfpSYxu+PQJ1qpx4ypwH6N+uF9twBPIvRRgvkvW5HUTYWENig==} + engines: {node: '>= 20'} - https-proxy-agent@7.0.6: - resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} - engines: {node: '>= 14'} + https-proxy-agent@9.1.0: + resolution: {integrity: sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==} + engines: {node: '>= 20'} iconv-lite@0.7.3: resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} @@ -1880,8 +1871,8 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.17.0: - resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} + is-core-module@2.18.0: + resolution: {integrity: sha512-qyax9fgaKOEC4qK8WZn7Q4IcoZC9RC1O1fFxRcRTq/oMMkWT/uXpqpXa12kzWR409zAt1drYN9N9BO26UmBCmw==} engines: {node: '>= 0.4'} is-data-view@1.0.2: @@ -2062,8 +2053,8 @@ packages: resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} engines: {node: '>=10'} - marked@18.1.2: - resolution: {integrity: sha512-DfOnvLAQ6WYeWxWO1u4RyFOeqyHup6dks5PPqnoFiooU7ipRvidO/2j8plhAHIiZg574E9ZlzSjUiPMLAzFkgg==} + marked@18.1.3: + resolution: {integrity: sha512-9ChMH8EVVgjgID49nsL6IWxWk5c6GtAsq/xw7U1ggkjkU5AGuv68oLTVlFRtvcUYZtpbNyjyvGo3YDu0fGapiw==} engines: {node: '>= 20'} hasBin: true @@ -2172,8 +2163,8 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - parse5@8.0.1: - resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + parse5@8.1.1: + resolution: {integrity: sha512-EcR/6WDcU7b2N3vQSxKALCk9lXGtUMQxXio008OEMBE0kavu/7JLfBEeFPzi43nMqVDSbEn3QCK+BMCc9zO//w==} path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} @@ -2222,6 +2213,15 @@ packages: proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + proxy-agent-negotiate@1.1.0: + resolution: {integrity: sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==} + engines: {node: '>= 20'} + peerDependencies: + kerberos: ^2.0.0 + peerDependenciesMeta: + kerberos: + optional: true + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2254,8 +2254,8 @@ packages: resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} engines: {node: '>=8'} - resolve@1.22.13: - resolution: {integrity: sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==} + resolve@1.22.14: + resolution: {integrity: sha512-1ZjYvR9sbkiwC5+9QHetqW5HmA2pHRMaoupD01t2HlYnV/vydC2zPwLixhsMieSWVZt0JJRg5LVIk0Ow1D/TrA==} engines: {node: '>= 0.4'} hasBin: true @@ -2294,12 +2294,12 @@ packages: resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} engines: {node: '>=11.0.0'} - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + semver@6.3.2: + resolution: {integrity: sha512-GYrCADwpu6yV5OAvchkQ27Z5wwMxWAEMg5NNWjyHh/5DboFFqbdbvYNIvZouQpxXyeMPoTOh0vdPYKlf0ZswdQ==} hasBin: true - semver@7.8.5: - resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + semver@7.8.6: + resolution: {integrity: sha512-9lpSSU4Mly3mrtruwLs1eLK6+gzbzqeBFwRNjIjE+9LuDpWdYctrQlQ3ej1Ilgi7gknpsTRnPoLP8DpCHqHIJw==} engines: {node: '>=10'} hasBin: true @@ -2539,32 +2539,35 @@ snapshots: '@azure/core-util': 1.14.0 tslib: 2.9.1 transitivePeerDependencies: + - kerberos - supports-color - '@azure/core-client@1.11.1': + '@azure/core-client@1.11.2': dependencies: '@azure/abort-controller': 2.2.0 '@azure/core-auth': 1.11.0 - '@azure/core-rest-pipeline': 1.25.0 + '@azure/core-rest-pipeline': 1.25.1 '@azure/core-tracing': 1.4.0 '@azure/core-util': 1.14.0 '@azure/logger': 1.4.0 tslib: 2.9.1 transitivePeerDependencies: + - kerberos - supports-color '@azure/core-process@1.0.0': {} - '@azure/core-rest-pipeline@1.25.0': + '@azure/core-rest-pipeline@1.25.1': dependencies: '@azure/abort-controller': 2.2.0 '@azure/core-auth': 1.11.0 '@azure/core-tracing': 1.4.0 '@azure/core-util': 1.14.0 '@azure/logger': 1.4.0 - '@typespec/ts-http-runtime': 0.3.9 + '@typespec/ts-http-runtime': 0.3.10 tslib: 2.9.1 transitivePeerDependencies: + - kerberos - supports-color '@azure/core-tracing@1.4.0': @@ -2574,44 +2577,47 @@ snapshots: '@azure/core-util@1.14.0': dependencies: '@azure/abort-controller': 2.2.0 - '@typespec/ts-http-runtime': 0.3.9 + '@typespec/ts-http-runtime': 0.3.10 tslib: 2.9.1 transitivePeerDependencies: + - kerberos - supports-color '@azure/identity@4.14.1': dependencies: '@azure/abort-controller': 2.2.0 '@azure/core-auth': 1.11.0 - '@azure/core-client': 1.11.1 + '@azure/core-client': 1.11.2 '@azure/core-process': 1.0.0 - '@azure/core-rest-pipeline': 1.25.0 + '@azure/core-rest-pipeline': 1.25.1 '@azure/core-tracing': 1.4.0 '@azure/core-util': 1.14.0 '@azure/logger': 1.4.0 - '@azure/msal-browser': 5.27.0 - '@azure/msal-node': 7.1.2 + '@azure/msal-browser': 5.29.0 + '@azure/msal-node': 7.2.1 open: 11.0.4 tslib: 2.9.1 transitivePeerDependencies: + - kerberos - supports-color '@azure/logger@1.4.0': dependencies: - '@typespec/ts-http-runtime': 0.3.9 + '@typespec/ts-http-runtime': 0.3.10 tslib: 2.9.1 transitivePeerDependencies: + - kerberos - supports-color - '@azure/msal-browser@5.27.0': + '@azure/msal-browser@5.29.0': dependencies: - '@azure/msal-common': 16.15.0 + '@azure/msal-common': 16.16.1 - '@azure/msal-common@16.15.0': {} + '@azure/msal-common@16.16.1': {} - '@azure/msal-node@7.1.2': + '@azure/msal-node@7.2.1': dependencies: - '@azure/msal-common': 16.15.0 + '@azure/msal-common': 16.16.1 jsonwebtoken: 9.0.3 '@cacheable/memory@2.2.0': @@ -2628,25 +2634,14 @@ snapshots: '@dual-bundle/import-meta-resolve@4.2.1': {} - '@emnapi/core@1.11.2': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.9.1 - optional: true - '@emnapi/core@1.11.3': dependencies: '@emnapi/wasi-threads': 1.2.3 tslib: 2.9.1 - '@emnapi/core@1.9.2': - dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.9.1 - optional: true - - '@emnapi/runtime@1.11.2': + '@emnapi/core@2.0.0-beta.3': dependencies: + '@emnapi/wasi-threads': 2.2.0 tslib: 2.9.1 optional: true @@ -2654,25 +2649,20 @@ snapshots: dependencies: tslib: 2.9.1 - '@emnapi/runtime@1.9.2': + '@emnapi/runtime@2.0.0-beta.3': dependencies: tslib: 2.9.1 optional: true - '@emnapi/wasi-threads@1.2.1': + '@emnapi/wasi-threads@1.2.3': dependencies: tslib: 2.9.1 - optional: true - '@emnapi/wasi-threads@1.2.2': + '@emnapi/wasi-threads@2.2.0': dependencies: tslib: 2.9.1 optional: true - '@emnapi/wasi-threads@1.2.3': - dependencies: - tslib: 2.9.1 - '@esbuild/aix-ppc64@0.28.2': optional: true @@ -2756,7 +2746,7 @@ snapshots: eslint: 10.14.0 eslint-visitor-keys: 3.4.3 - '@eslint-community/regexpp@4.12.2': {} + '@eslint-community/regexpp@4.12.3': {} '@eslint/config-array@0.23.5': dependencies: @@ -2928,18 +2918,18 @@ snapshots: '@keyv/serialize@1.1.1': {} - '@napi-rs/cli@3.10.9(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.6.6)': + '@napi-rs/cli@3.10.12(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)(@types/node@26.6.6)': dependencies: '@inquirer/prompts': 8.7.5(@types/node@26.6.6) - '@napi-rs/cross-toolchain': 1.0.3 - '@napi-rs/wasm-tools': 1.1.0 + '@napi-rs/cross-toolchain': 1.0.5 + '@napi-rs/wasm-tools': 1.1.2 '@octokit/rest': 22.0.1 clipanion: 4.0.0-rc.4(typanion@3.14.0) colorette: 2.0.20 - es-toolkit: 1.53.1 + es-toolkit: 1.53.2 js-yaml: 5.5.0 obug: 3.0.0 - semver: 7.8.5 + semver: 7.8.6 typanion: 3.14.0 typescript: 6.0.3 optionalDependencies: @@ -2959,10 +2949,10 @@ snapshots: - '@types/node' - supports-color - '@napi-rs/cross-toolchain@1.0.3': + '@napi-rs/cross-toolchain@1.0.5': dependencies: - '@napi-rs/lzma': 1.5.1 - '@napi-rs/tar': 1.1.1 + '@napi-rs/lzma': 1.5.3 + '@napi-rs/tar': 1.1.3 debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -3018,224 +3008,217 @@ snapshots: '@napi-rs/keyring-win32-ia32-msvc': 1.3.0 '@napi-rs/keyring-win32-x64-msvc': 1.3.0 - '@napi-rs/lzma-android-arm-eabi@1.5.1': + '@napi-rs/lzma-android-arm-eabi@1.5.3': optional: true - '@napi-rs/lzma-android-arm64@1.5.1': + '@napi-rs/lzma-android-arm64@1.5.3': optional: true - '@napi-rs/lzma-darwin-arm64@1.5.1': + '@napi-rs/lzma-darwin-arm64@1.5.3': optional: true - '@napi-rs/lzma-darwin-x64@1.5.1': + '@napi-rs/lzma-darwin-x64@1.5.3': optional: true - '@napi-rs/lzma-freebsd-x64@1.5.1': + '@napi-rs/lzma-freebsd-x64@1.5.3': optional: true - '@napi-rs/lzma-linux-arm-gnueabihf@1.5.1': + '@napi-rs/lzma-linux-arm-gnueabihf@1.5.3': optional: true - '@napi-rs/lzma-linux-arm64-gnu@1.5.1': + '@napi-rs/lzma-linux-arm64-gnu@1.5.3': optional: true - '@napi-rs/lzma-linux-arm64-musl@1.5.1': + '@napi-rs/lzma-linux-arm64-musl@1.5.3': optional: true - '@napi-rs/lzma-linux-ppc64-gnu@1.5.1': + '@napi-rs/lzma-linux-ppc64-gnu@1.5.3': optional: true - '@napi-rs/lzma-linux-riscv64-gnu@1.5.1': + '@napi-rs/lzma-linux-riscv64-gnu@1.5.3': optional: true - '@napi-rs/lzma-linux-s390x-gnu@1.5.1': + '@napi-rs/lzma-linux-s390x-gnu@1.5.3': optional: true - '@napi-rs/lzma-linux-x64-gnu@1.5.1': + '@napi-rs/lzma-linux-x64-gnu@1.5.3': optional: true - '@napi-rs/lzma-linux-x64-musl@1.5.1': + '@napi-rs/lzma-linux-x64-musl@1.5.3': optional: true - '@napi-rs/lzma-wasm32-wasi@1.5.1': + '@napi-rs/lzma-wasm32-wasi@1.5.3': dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@napi-rs/wasm-runtime': 1.2.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + '@emnapi/core': 2.0.0-beta.3 + '@emnapi/runtime': 2.0.0-beta.3 + '@napi-rs/wasm-runtime': 1.2.7(@emnapi/core@2.0.0-beta.3)(@emnapi/runtime@2.0.0-beta.3) optional: true - '@napi-rs/lzma-win32-arm64-msvc@1.5.1': + '@napi-rs/lzma-win32-arm64-msvc@1.5.3': optional: true - '@napi-rs/lzma-win32-ia32-msvc@1.5.1': + '@napi-rs/lzma-win32-ia32-msvc@1.5.3': optional: true - '@napi-rs/lzma-win32-x64-msvc@1.5.1': + '@napi-rs/lzma-win32-x64-msvc@1.5.3': optional: true - '@napi-rs/lzma@1.5.1': + '@napi-rs/lzma@1.5.3': optionalDependencies: - '@napi-rs/lzma-android-arm-eabi': 1.5.1 - '@napi-rs/lzma-android-arm64': 1.5.1 - '@napi-rs/lzma-darwin-arm64': 1.5.1 - '@napi-rs/lzma-darwin-x64': 1.5.1 - '@napi-rs/lzma-freebsd-x64': 1.5.1 - '@napi-rs/lzma-linux-arm-gnueabihf': 1.5.1 - '@napi-rs/lzma-linux-arm64-gnu': 1.5.1 - '@napi-rs/lzma-linux-arm64-musl': 1.5.1 - '@napi-rs/lzma-linux-ppc64-gnu': 1.5.1 - '@napi-rs/lzma-linux-riscv64-gnu': 1.5.1 - '@napi-rs/lzma-linux-s390x-gnu': 1.5.1 - '@napi-rs/lzma-linux-x64-gnu': 1.5.1 - '@napi-rs/lzma-linux-x64-musl': 1.5.1 - '@napi-rs/lzma-wasm32-wasi': 1.5.1 - '@napi-rs/lzma-win32-arm64-msvc': 1.5.1 - '@napi-rs/lzma-win32-ia32-msvc': 1.5.1 - '@napi-rs/lzma-win32-x64-msvc': 1.5.1 - - '@napi-rs/tar-android-arm-eabi@1.1.1': + '@napi-rs/lzma-android-arm-eabi': 1.5.3 + '@napi-rs/lzma-android-arm64': 1.5.3 + '@napi-rs/lzma-darwin-arm64': 1.5.3 + '@napi-rs/lzma-darwin-x64': 1.5.3 + '@napi-rs/lzma-freebsd-x64': 1.5.3 + '@napi-rs/lzma-linux-arm-gnueabihf': 1.5.3 + '@napi-rs/lzma-linux-arm64-gnu': 1.5.3 + '@napi-rs/lzma-linux-arm64-musl': 1.5.3 + '@napi-rs/lzma-linux-ppc64-gnu': 1.5.3 + '@napi-rs/lzma-linux-riscv64-gnu': 1.5.3 + '@napi-rs/lzma-linux-s390x-gnu': 1.5.3 + '@napi-rs/lzma-linux-x64-gnu': 1.5.3 + '@napi-rs/lzma-linux-x64-musl': 1.5.3 + '@napi-rs/lzma-wasm32-wasi': 1.5.3 + '@napi-rs/lzma-win32-arm64-msvc': 1.5.3 + '@napi-rs/lzma-win32-ia32-msvc': 1.5.3 + '@napi-rs/lzma-win32-x64-msvc': 1.5.3 + + '@napi-rs/tar-android-arm-eabi@1.1.3': optional: true - '@napi-rs/tar-android-arm64@1.1.1': + '@napi-rs/tar-android-arm64@1.1.3': optional: true - '@napi-rs/tar-darwin-arm64@1.1.1': + '@napi-rs/tar-darwin-arm64@1.1.3': optional: true - '@napi-rs/tar-darwin-x64@1.1.1': + '@napi-rs/tar-darwin-x64@1.1.3': optional: true - '@napi-rs/tar-freebsd-x64@1.1.1': + '@napi-rs/tar-freebsd-x64@1.1.3': optional: true - '@napi-rs/tar-linux-arm-gnueabihf@1.1.1': + '@napi-rs/tar-linux-arm-gnueabihf@1.1.3': optional: true - '@napi-rs/tar-linux-arm64-gnu@1.1.1': + '@napi-rs/tar-linux-arm64-gnu@1.1.3': optional: true - '@napi-rs/tar-linux-arm64-musl@1.1.1': + '@napi-rs/tar-linux-arm64-musl@1.1.3': optional: true - '@napi-rs/tar-linux-ppc64-gnu@1.1.1': + '@napi-rs/tar-linux-ppc64-gnu@1.1.3': optional: true - '@napi-rs/tar-linux-s390x-gnu@1.1.1': + '@napi-rs/tar-linux-s390x-gnu@1.1.3': optional: true - '@napi-rs/tar-linux-x64-gnu@1.1.1': + '@napi-rs/tar-linux-x64-gnu@1.1.3': optional: true - '@napi-rs/tar-linux-x64-musl@1.1.1': + '@napi-rs/tar-linux-x64-musl@1.1.3': optional: true - '@napi-rs/tar-wasm32-wasi@1.1.1': + '@napi-rs/tar-wasm32-wasi@1.1.3': dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@napi-rs/wasm-runtime': 1.2.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + '@emnapi/core': 2.0.0-beta.3 + '@emnapi/runtime': 2.0.0-beta.3 + '@napi-rs/wasm-runtime': 1.2.7(@emnapi/core@2.0.0-beta.3)(@emnapi/runtime@2.0.0-beta.3) optional: true - '@napi-rs/tar-win32-arm64-msvc@1.1.1': + '@napi-rs/tar-win32-arm64-msvc@1.1.3': optional: true - '@napi-rs/tar-win32-ia32-msvc@1.1.1': + '@napi-rs/tar-win32-ia32-msvc@1.1.3': optional: true - '@napi-rs/tar-win32-x64-msvc@1.1.1': + '@napi-rs/tar-win32-x64-msvc@1.1.3': optional: true - '@napi-rs/tar@1.1.1': + '@napi-rs/tar@1.1.3': optionalDependencies: - '@napi-rs/tar-android-arm-eabi': 1.1.1 - '@napi-rs/tar-android-arm64': 1.1.1 - '@napi-rs/tar-darwin-arm64': 1.1.1 - '@napi-rs/tar-darwin-x64': 1.1.1 - '@napi-rs/tar-freebsd-x64': 1.1.1 - '@napi-rs/tar-linux-arm-gnueabihf': 1.1.1 - '@napi-rs/tar-linux-arm64-gnu': 1.1.1 - '@napi-rs/tar-linux-arm64-musl': 1.1.1 - '@napi-rs/tar-linux-ppc64-gnu': 1.1.1 - '@napi-rs/tar-linux-s390x-gnu': 1.1.1 - '@napi-rs/tar-linux-x64-gnu': 1.1.1 - '@napi-rs/tar-linux-x64-musl': 1.1.1 - '@napi-rs/tar-wasm32-wasi': 1.1.1 - '@napi-rs/tar-win32-arm64-msvc': 1.1.1 - '@napi-rs/tar-win32-ia32-msvc': 1.1.1 - '@napi-rs/tar-win32-x64-msvc': 1.1.1 - - '@napi-rs/wasm-runtime@1.2.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': - dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 + '@napi-rs/tar-android-arm-eabi': 1.1.3 + '@napi-rs/tar-android-arm64': 1.1.3 + '@napi-rs/tar-darwin-arm64': 1.1.3 + '@napi-rs/tar-darwin-x64': 1.1.3 + '@napi-rs/tar-freebsd-x64': 1.1.3 + '@napi-rs/tar-linux-arm-gnueabihf': 1.1.3 + '@napi-rs/tar-linux-arm64-gnu': 1.1.3 + '@napi-rs/tar-linux-arm64-musl': 1.1.3 + '@napi-rs/tar-linux-ppc64-gnu': 1.1.3 + '@napi-rs/tar-linux-s390x-gnu': 1.1.3 + '@napi-rs/tar-linux-x64-gnu': 1.1.3 + '@napi-rs/tar-linux-x64-musl': 1.1.3 + '@napi-rs/tar-wasm32-wasi': 1.1.3 + '@napi-rs/tar-win32-arm64-msvc': 1.1.3 + '@napi-rs/tar-win32-ia32-msvc': 1.1.3 + '@napi-rs/tar-win32-x64-msvc': 1.1.3 + + '@napi-rs/wasm-runtime@1.2.7(@emnapi/core@2.0.0-beta.3)(@emnapi/runtime@2.0.0-beta.3)': + dependencies: + '@emnapi/core': 2.0.0-beta.3 + '@emnapi/runtime': 2.0.0-beta.3 '@tybys/wasm-util': 0.10.4 optional: true - '@napi-rs/wasm-runtime@1.2.6(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)': - dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@tybys/wasm-util': 0.10.4 - optional: true - - '@napi-rs/wasm-tools-android-arm-eabi@1.1.0': + '@napi-rs/wasm-tools-android-arm-eabi@1.1.2': optional: true - '@napi-rs/wasm-tools-android-arm64@1.1.0': + '@napi-rs/wasm-tools-android-arm64@1.1.2': optional: true - '@napi-rs/wasm-tools-darwin-arm64@1.1.0': + '@napi-rs/wasm-tools-darwin-arm64@1.1.2': optional: true - '@napi-rs/wasm-tools-darwin-x64@1.1.0': + '@napi-rs/wasm-tools-darwin-x64@1.1.2': optional: true - '@napi-rs/wasm-tools-freebsd-x64@1.1.0': + '@napi-rs/wasm-tools-freebsd-x64@1.1.2': optional: true - '@napi-rs/wasm-tools-linux-arm64-gnu@1.1.0': + '@napi-rs/wasm-tools-linux-arm64-gnu@1.1.2': optional: true - '@napi-rs/wasm-tools-linux-arm64-musl@1.1.0': + '@napi-rs/wasm-tools-linux-arm64-musl@1.1.2': optional: true - '@napi-rs/wasm-tools-linux-x64-gnu@1.1.0': + '@napi-rs/wasm-tools-linux-x64-gnu@1.1.2': optional: true - '@napi-rs/wasm-tools-linux-x64-musl@1.1.0': + '@napi-rs/wasm-tools-linux-x64-musl@1.1.2': optional: true - '@napi-rs/wasm-tools-wasm32-wasi@1.1.0': + '@napi-rs/wasm-tools-wasm32-wasi@1.1.2': dependencies: - '@emnapi/core': 1.9.2 - '@emnapi/runtime': 1.9.2 - '@napi-rs/wasm-runtime': 1.2.6(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + '@emnapi/core': 2.0.0-beta.3 + '@emnapi/runtime': 2.0.0-beta.3 + '@napi-rs/wasm-runtime': 1.2.7(@emnapi/core@2.0.0-beta.3)(@emnapi/runtime@2.0.0-beta.3) optional: true - '@napi-rs/wasm-tools-win32-arm64-msvc@1.1.0': + '@napi-rs/wasm-tools-win32-arm64-msvc@1.1.2': optional: true - '@napi-rs/wasm-tools-win32-ia32-msvc@1.1.0': + '@napi-rs/wasm-tools-win32-ia32-msvc@1.1.2': optional: true - '@napi-rs/wasm-tools-win32-x64-msvc@1.1.0': + '@napi-rs/wasm-tools-win32-x64-msvc@1.1.2': optional: true - '@napi-rs/wasm-tools@1.1.0': + '@napi-rs/wasm-tools@1.1.2': optionalDependencies: - '@napi-rs/wasm-tools-android-arm-eabi': 1.1.0 - '@napi-rs/wasm-tools-android-arm64': 1.1.0 - '@napi-rs/wasm-tools-darwin-arm64': 1.1.0 - '@napi-rs/wasm-tools-darwin-x64': 1.1.0 - '@napi-rs/wasm-tools-freebsd-x64': 1.1.0 - '@napi-rs/wasm-tools-linux-arm64-gnu': 1.1.0 - '@napi-rs/wasm-tools-linux-arm64-musl': 1.1.0 - '@napi-rs/wasm-tools-linux-x64-gnu': 1.1.0 - '@napi-rs/wasm-tools-linux-x64-musl': 1.1.0 - '@napi-rs/wasm-tools-wasm32-wasi': 1.1.0 - '@napi-rs/wasm-tools-win32-arm64-msvc': 1.1.0 - '@napi-rs/wasm-tools-win32-ia32-msvc': 1.1.0 - '@napi-rs/wasm-tools-win32-x64-msvc': 1.1.0 + '@napi-rs/wasm-tools-android-arm-eabi': 1.1.2 + '@napi-rs/wasm-tools-android-arm64': 1.1.2 + '@napi-rs/wasm-tools-darwin-arm64': 1.1.2 + '@napi-rs/wasm-tools-darwin-x64': 1.1.2 + '@napi-rs/wasm-tools-freebsd-x64': 1.1.2 + '@napi-rs/wasm-tools-linux-arm64-gnu': 1.1.2 + '@napi-rs/wasm-tools-linux-arm64-musl': 1.1.2 + '@napi-rs/wasm-tools-linux-x64-gnu': 1.1.2 + '@napi-rs/wasm-tools-linux-x64-musl': 1.1.2 + '@napi-rs/wasm-tools-wasm32-wasi': 1.1.2 + '@napi-rs/wasm-tools-win32-arm64-msvc': 1.1.2 + '@napi-rs/wasm-tools-win32-ia32-msvc': 1.1.2 + '@napi-rs/wasm-tools-win32-x64-msvc': 1.1.2 '@octokit/auth-token@6.0.0': {} @@ -3356,7 +3339,7 @@ snapshots: '@typescript-eslint/eslint-plugin@8.72.1(@typescript-eslint/parser@8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0))(@typescript/typescript6@6.0.2)(eslint@10.14.0)': dependencies: - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/regexpp': 4.12.3 '@typescript-eslint/parser': 8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0) '@typescript-eslint/scope-manager': 8.72.1 '@typescript-eslint/type-utils': 8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0) @@ -3422,7 +3405,7 @@ snapshots: '@typescript-eslint/visitor-keys': 8.72.1 debug: 4.4.3 minimatch: 10.2.6 - semver: 7.8.5 + semver: 7.8.6 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(@typescript/typescript6@6.0.2) typescript: '@typescript/typescript6@6.0.2' @@ -3509,12 +3492,13 @@ snapshots: dependencies: '@typescript/old': typescript@6.0.3 - '@typespec/ts-http-runtime@0.3.9': + '@typespec/ts-http-runtime@0.3.10': dependencies: - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 + http-proxy-agent: 9.1.0 + https-proxy-agent: 9.1.0 tslib: 2.9.1 transitivePeerDependencies: + - kerberos - supports-color '@vscode/vsce-sign-alpine-arm64@2.0.6': @@ -3571,13 +3555,13 @@ snapshots: commander: 12.1.0 hosted-git-info: 4.1.0 jsonc-parser: 3.3.1 - marked: 18.1.2 + marked: 18.1.3 mime: 1.6.0 minimatch: 10.2.6 - parse5: 8.0.1 + parse5: 8.1.1 proper-lockfile: 4.1.2 read: 1.0.7 - semver: 7.8.5 + semver: 7.8.6 tinyglobby: 0.2.17 typed-rest-client: 1.8.11 url-join: 4.0.1 @@ -3585,6 +3569,7 @@ snapshots: yauzl: 3.4.0 yazl: 2.5.1 transitivePeerDependencies: + - kerberos - supports-color acorn-jsx@5.3.2(acorn@8.19.0): @@ -3593,7 +3578,7 @@ snapshots: acorn@8.19.0: {} - agent-base@7.1.4: {} + agent-base@9.0.0: {} ajv@6.15.0: dependencies: @@ -3692,7 +3677,7 @@ snapshots: buffer-equal-constant-time@1.0.1: {} - bufferutil@4.1.0: + bufferutil@4.2.0: dependencies: node-gyp-build: 4.8.4 optional: true @@ -3819,7 +3804,7 @@ snapshots: dependencies: version-range: 4.15.0 - entities@8.1.0: {} + entities@9.0.0: {} es-abstract-get@1.0.0: dependencies: @@ -3913,7 +3898,7 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 - es-toolkit@1.53.1: {} + es-toolkit@1.53.2: {} esbuild@0.28.2: optionalDependencies: @@ -3955,7 +3940,7 @@ snapshots: eslint-import-resolver-node@0.3.10: dependencies: debug: 3.2.7 - is-core-module: 2.17.0 + is-core-module: 2.18.0 resolve: 2.0.0-next.7 transitivePeerDependencies: - supports-color @@ -3989,13 +3974,13 @@ snapshots: eslint-import-resolver-node: 0.3.10 eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.72.1(@typescript/typescript6@6.0.2)(eslint@10.14.0))(eslint-import-resolver-node@0.3.10)(eslint@10.14.0) hasown: 2.0.4 - is-core-module: 2.17.0 + is-core-module: 2.18.0 is-glob: 4.0.3 minimatch: 3.1.5 object.fromentries: 2.0.8 object.groupby: 1.0.3 object.values: 1.2.1 - semver: 6.3.1 + semver: 6.3.2 string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: @@ -4012,8 +3997,8 @@ snapshots: eslint-utils: 2.1.0 ignore: 5.3.2 minimatch: 3.1.5 - resolve: 1.22.13 - semver: 6.3.1 + resolve: 1.22.14 + semver: 6.3.2 eslint-plugin-prettier@5.5.7(eslint-config-prettier@10.1.8(eslint@10.14.0))(eslint@10.14.0)(prettier@3.9.10): dependencies: @@ -4044,7 +4029,7 @@ snapshots: eslint@10.14.0: dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.14.0) - '@eslint-community/regexpp': 4.12.2 + '@eslint-community/regexpp': 4.12.3 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.7.0 '@eslint/core': 1.2.1 @@ -4224,18 +4209,22 @@ snapshots: dependencies: lru-cache: 6.0.0 - http-proxy-agent@7.0.2: + http-proxy-agent@9.1.0: dependencies: - agent-base: 7.1.4 + agent-base: 9.0.0 debug: 4.4.3 + proxy-agent-negotiate: 1.1.0 transitivePeerDependencies: + - kerberos - supports-color - https-proxy-agent@7.0.6: + https-proxy-agent@9.1.0: dependencies: - agent-base: 7.1.4 + agent-base: 9.0.0 debug: 4.4.3 + proxy-agent-negotiate: 1.1.0 transitivePeerDependencies: + - kerberos - supports-color iconv-lite@0.7.3: @@ -4279,7 +4268,7 @@ snapshots: is-callable@1.2.7: {} - is-core-module@2.17.0: + is-core-module@2.18.0: dependencies: hasown: 2.0.4 @@ -4417,7 +4406,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.8.5 + semver: 7.8.6 jwa@2.0.1: dependencies: @@ -4461,7 +4450,7 @@ snapshots: dependencies: yallist: 4.0.0 - marked@18.1.2: {} + marked@18.1.3: {} math-intrinsics@1.1.0: {} @@ -4492,7 +4481,7 @@ snapshots: array.prototype.flatmap: 1.3.3 es-errors: 1.3.0 object.entries: 1.1.9 - semver: 6.3.1 + semver: 6.3.2 node-gyp-build@4.8.4: optional: true @@ -4585,9 +4574,9 @@ snapshots: dependencies: p-limit: 3.1.0 - parse5@8.0.1: + parse5@8.1.1: dependencies: - entities: 8.1.0 + entities: 9.0.0 path-exists@4.0.0: {} @@ -4619,6 +4608,8 @@ snapshots: retry: 0.12.0 signal-exit: 3.0.7 + proxy-agent-negotiate@1.1.0: {} + punycode@2.3.1: {} qified@0.10.1: @@ -4661,17 +4652,17 @@ snapshots: regexpp@3.2.0: {} - resolve@1.22.13: + resolve@1.22.14: dependencies: es-errors: 1.3.0 - is-core-module: 2.17.0 + is-core-module: 2.18.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 resolve@2.0.0-next.7: dependencies: es-errors: 1.3.0 - is-core-module: 2.17.0 + is-core-module: 2.18.0 node-exports-info: 1.6.2 object-keys: 1.1.1 path-parse: 1.0.7 @@ -4706,9 +4697,9 @@ snapshots: sax@1.6.1: {} - semver@6.3.1: {} + semver@6.3.2: {} - semver@7.8.5: {} + semver@7.8.6: {} set-function-length@1.2.2: dependencies: diff --git a/server/Cargo.toml b/server/Cargo.toml index 3e905e49..ca5f4865 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -56,7 +56,7 @@ dunce = "1.0.5" futures-util = "0.3.29" htmd = { git = "https://github.com/bjones1/htmd.git", branch = "dom-interface", version = "0.5" } # This must match the version of `markup5ever_rcdom`. -html5ever = "0.39" +html5ever = "0.40" htmlize = { version = "1.0.6", features = ["unescape"] } ignore = "0.4" imara-diff = { version = "0.2", features = [] } @@ -64,7 +64,7 @@ indoc = "2.0.5" log.workspace = true log4rs = "1.3" lru = "0.19" -markup5ever_rcdom = "0.39" +markup5ever_rcdom = "0.40" mime = "0.3.17" mime_guess = "2.0.5" minify-html = { git = "https://github.com/bjones1/minify-html.git", branch = "dev", version = "0.18.1" } From 061a0a1d1adec084b949bfa204ac0f67e7cc3cdb Mon Sep 17 00:00:00 2001 From: "Bryan A. Jones" Date: Mon, 9 Nov 2026 22:13:52 -0600 Subject: [PATCH 29/29] Test: click a doc block's contents, not the indent covering its top left. An empty indent is 1ch wide, which covers the click point of `click_element_top_left` except with Consolas, so these tests failed on Linux and macOS. Type after pressing Home, since the caret's position after a click depends on the font, and click the doc block before typing in the read-only code block, which moves TinyMCE into the doc block. Co-Authored-By: Claude Opus 5.5 --- server/tests/overall/overall_2.rs | 52 ++++++++++++++++--------------- server/tests/overall/overall_5.rs | 34 ++++++++++++++------ 2 files changed, 52 insertions(+), 34 deletions(-) diff --git a/server/tests/overall/overall_2.rs b/server/tests/overall/overall_2.rs index 663ce9a1..9291eaa2 100644 --- a/server/tests/overall/overall_2.rs +++ b/server/tests/overall/overall_2.rs @@ -39,8 +39,8 @@ use thirtyfour::{ // ### Local use crate::common::{ CodeChatEditorServerLog, DOC_BLOCK_CSS, TIMEOUT, assert_no_more_messages, - beginning_of_document, click_element_top_left, get_version, optional_message, perform_loadfile, - select_codechat_iframe, + beginning_of_document, beginning_of_line, click_element_top_left, get_version, + optional_message, perform_loadfile, select_codechat_iframe, }; use crate::make_test; use code_chat_editor::{ @@ -207,35 +207,36 @@ async fn test_5_core( // Target the iframe containing the Client. select_codechat_iframe(&driver).await; - // Focus it. + // Focus it. Click its contents, not the enclosing `.CodeChat-doc`, whose + // top left is covered by the empty indent on most platforms; see + // `test_xref_optional_content_round_trip_core` in + // [overall\_5.rs](overall_5.rs). let doc_block_contents = driver - .query(By::Css(".CodeChat-doc")) + .query(By::Css(".CodeChat-doc-contents")) .first() .await .unwrap(); click_element_top_left(&driver, &doc_block_contents) .await .unwrap(); - // The click sometimes produces an updated cursor/scroll location after an - // autosave delay; absorb that message when it appears, then continue. + // The click produces an updated cursor/scroll location after an autosave + // delay. let mut client_id = INITIAL_CLIENT_MESSAGE_ID; - if let Some(msg) = codechat_server.get_message_timeout(TIMEOUT).await { - assert_eq!( - msg, - EditorMessage { - id: client_id, - message: EditorMessageContents::Update(UpdateMessageContents { - file_path: path_str.clone(), - cursor_position: Some(CursorPosition::Line(1)), - scroll_position: Some(1.0), - is_re_translation: false, - contents: None, - }) - } - ); - codechat_server.send_result(client_id, None).await.unwrap(); - client_id += MESSAGE_ID_INCREMENT; - } + assert_eq!( + codechat_server.get_message_timeout(TIMEOUT).await.unwrap(), + EditorMessage { + id: client_id, + message: EditorMessageContents::Update(UpdateMessageContents { + file_path: path_str.clone(), + cursor_position: Some(CursorPosition::Line(1)), + scroll_position: Some(1.0), + is_re_translation: false, + contents: None, + }) + } + ); + codechat_server.send_result(client_id, None).await.unwrap(); + client_id += MESSAGE_ID_INCREMENT; // Refind it, since it's now switched with a TinyMCE editor. let tinymce_contents = driver.query(By::Id("TinyMCE-inst")).first().await.unwrap(); @@ -243,8 +244,9 @@ async fn test_5_core( // switch from the doc block to the TinyMCE editor can leave the element // briefly present but not yet interactable. tinymce_contents.wait_until().clickable().await.unwrap(); - // Make an edit. - tinymce_contents.send_keys("foo").await.unwrap(); + // Make an edit at the start of the line, since where the click places the + // caret depends on the font. + beginning_of_line(&tinymce_contents, "foo").await.unwrap(); // Verify the updated text. // diff --git a/server/tests/overall/overall_5.rs b/server/tests/overall/overall_5.rs index 49dc4918..d18dfd51 100644 --- a/server/tests/overall/overall_5.rs +++ b/server/tests/overall/overall_5.rs @@ -885,8 +885,15 @@ async fn test_xref_optional_content_round_trip_core( select_codechat_iframe(&driver).await; // Move the TinyMCE editor into the doc block by clicking on its heading. + // Click its contents, not the enclosing `.CodeChat-doc`: the top left of + // that is covered by the empty indent, which is 1ch wide (see + // `.CodeChat-doc-indent:empty` in + // [CodeChatEditorBase.css](../../../client/src/css/CodeChatEditorBase.css)). + // Except for Consolas, which only Windows has, a 1ch indent is wide enough + // to take the click, which then neither moves TinyMCE nor sends a cursor + // update. let doc_block_contents = driver - .query(By::Css(".CodeChat-doc")) + .query(By::Css(".CodeChat-doc-contents")) .first() .await .unwrap(); @@ -922,7 +929,9 @@ async fn test_xref_optional_content_round_trip_core( .first() .await .unwrap(); - tinymce_contents.send_keys("z").await.unwrap(); + // Type at the start of the heading, since where the click places the caret + // depends on the font. + beginning_of_line(&tinymce_contents, "z").await.unwrap(); // Only the heading changes. let msg = optional_message(&codechat_server, &mut client_id, cursor_update()).await; @@ -1034,18 +1043,25 @@ async fn test_untranslatable_source_toast_core( "Unexpected toast: {toast_text}" ); - // Typing in a code block, then in a doc block, changes neither. The only - // line of code is the blank line which follows the doc block. - let code_line_css = By::Css(".cm-line"); - let code_line = driver.query(code_line_css.clone()).first().await?; - code_line.click().await?; - code_line.send_keys("y").await?; - let doc_block = driver.query(By::Css(".CodeChat-doc")).first().await?; + // Typing in a doc block, then in a code block, changes neither. The doc + // block comes first: typing in the read-only code block moves TinyMCE into + // the doc block, which would replace the contents div clicked below. Click + // the contents, for the reason given in + // `test_xref_optional_content_round_trip_core`. + let doc_block = driver + .query(By::Css(".CodeChat-doc-contents")) + .first() + .await?; click_element_top_left(&driver, &doc_block).await?; // Find TinyMCE once the click moves it into the doc block. let tinymce_contents = driver.query(By::Id("TinyMCE-inst")).first().await?; tinymce_contents.wait_until().clickable().await?; tinymce_contents.send_keys("z").await?; + // The only line of code is the blank line which follows the doc block. + let code_line_css = By::Css(".cm-line"); + let code_line = driver.query(code_line_css.clone()).first().await?; + code_line.click().await?; + code_line.send_keys("y").await?; // Only the cursor moves. This also gives a second toast time to appear, as // it would if the Client sent an edit, which the Server rejects. let mut client_id = INITIAL_CLIENT_MESSAGE_ID;