From 0e5317997a45140843bf5c93ec23c685ab7edab7 Mon Sep 17 00:00:00 2001 From: Alteras1 <42795314+Alteras1@users.noreply.github.com.> Date: Thu, 25 Sep 2025 09:32:30 -0700 Subject: [PATCH 01/15] Extend post serializer and add hooks to detect rolls in cooked --- app/controllers/rollmaster/roll_controller.rb | 12 ++++++ app/serializers/rollmaster/roll_serializer.rb | 7 ++++ .../components/rolls-post-menu-button.gjs | 42 +++++++++++++++++++ .../discourse/initializers/decorate-post.js | 36 ++++++++++++++++ config/locales/client.en.yml | 2 + config/routes.rb | 2 +- lib/rollmaster/handle_cooked_post_process.rb | 2 + plugin.rb | 13 +++++- spec/integration/bbcode_spec.rb | 1 + 9 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 app/serializers/rollmaster/roll_serializer.rb create mode 100644 assets/javascripts/discourse/components/rolls-post-menu-button.gjs create mode 100644 assets/javascripts/discourse/initializers/decorate-post.js diff --git a/app/controllers/rollmaster/roll_controller.rb b/app/controllers/rollmaster/roll_controller.rb index b17d5ac..6f932ee 100644 --- a/app/controllers/rollmaster/roll_controller.rb +++ b/app/controllers/rollmaster/roll_controller.rb @@ -16,5 +16,17 @@ def roll raise Discourse::InvalidParameters, e.message end end + + # GET /rollmaster/rolls/:post_id + # @param [Integer] post_id the ID of the post to get rolls for + # @return [Array] rolls array of rolls associated with the post + # @example URL /rollmaster/rolls/123 + def rolls + post_id = params[:post_id] + raise Discourse::InvalidParameters, "post_id is required" if post_id.blank? + + rolls = ::Rollmaster::Roll.where(post_id: post_id) + render_serialized(rolls, Rollmaster::RollSerializer, root: "rolls") + end end end diff --git a/app/serializers/rollmaster/roll_serializer.rb b/app/serializers/rollmaster/roll_serializer.rb new file mode 100644 index 0000000..5b520a6 --- /dev/null +++ b/app/serializers/rollmaster/roll_serializer.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module ::Rollmaster + class RollSerializer < ApplicationSerializer + attributes :id, :post_id, :raw, :notation, :result, :created_at, :updated_at + end +end diff --git a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs new file mode 100644 index 0000000..04a3531 --- /dev/null +++ b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs @@ -0,0 +1,42 @@ +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { action } from "@ember/object"; +import DButton from "discourse/components/d-button"; +import { i18n } from "discourse-i18n"; +import DModal from "discourse/components/d-modal"; +import { fn } from "@ember/helper"; + +export default class RollsPostMenuButton extends Component { + static hidden() { + return false; + } + + @tracked rolls = this.args.post.rolls || []; + @tracked modalIsOpen = false; + + @action + showRolls() { + console.log("Rolls:", this.rolls); + // Implement the logic to show rolls, e.g., open a modal or dropdown + this.modalIsOpen = true; + } + + +} diff --git a/assets/javascripts/discourse/initializers/decorate-post.js b/assets/javascripts/discourse/initializers/decorate-post.js new file mode 100644 index 0000000..6eb3aba --- /dev/null +++ b/assets/javascripts/discourse/initializers/decorate-post.js @@ -0,0 +1,36 @@ +import { withPluginApi } from "discourse/lib/plugin-api"; +import RollsPostMenuButton from "../components/rolls-post-menu-button"; + +function decorateCookedElement(el, helper) { + if (!helper?.getModel()?.has_rolls) { + return; + } + + const rolls = helper.getModel().rolls; + const rollElems = el.querySelectorAll( + ".bb-rollmaster[data-notation][data-roll-id]" + ); + console.log(rollElems, rolls); +} + +export default { + name: "rollmaster-decorate-post", + initialize() { + withPluginApi((api) => { + api.decorateCookedElement(decorateCookedElement); + + api.registerValueTransformer( + "post-menu-buttons", + ({ value: dag, context: { post } }) => { + if (!post.has_rolls) { + return; + } + dag.add("rollmaster-view-rolls", RollsPostMenuButton, { + before: ["delete", "showMore"], + after: ["bookmark", "edit"], + }); + } + ); + }); + }, +}; diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index d976371..eb7041c 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -6,6 +6,8 @@ en: rollmaster: "Rollmaster" js: rollmaster: + post: + title: "view rolls made in this post" bbcode: placeholder: "Rolling: " validator: diff --git a/config/routes.rb b/config/routes.rb index a8e2b60..632cdbf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,7 @@ Rollmaster::Engine.routes.draw do get "/roll" => "roll#roll" - # define routes here + get "/rolls/:post_id" => "roll#rolls" end Discourse::Application.routes.draw { mount ::Rollmaster::Engine, at: "rollmaster" } diff --git a/lib/rollmaster/handle_cooked_post_process.rb b/lib/rollmaster/handle_cooked_post_process.rb index b63cef7..b20d2a9 100644 --- a/lib/rollmaster/handle_cooked_post_process.rb +++ b/lib/rollmaster/handle_cooked_post_process.rb @@ -94,6 +94,8 @@ def self.match_rolls(rolls, post) end def self.save_rolls(rolls, post) + post.custom_fields[::Rollmaster::POST_CUSTOM_FIELD] = true + post.save_custom_fields rolls .reject { |r| r[:raw].empty? || r[:error] } .each do |roll| diff --git a/plugin.rb b/plugin.rb index 9d86e74..2406d11 100644 --- a/plugin.rb +++ b/plugin.rb @@ -13,7 +13,8 @@ register_asset "stylesheets/common/index.scss" module ::Rollmaster - PLUGIN_NAME = "rollmaster" + PLUGIN_NAME = "rollmaster".freeze + POST_CUSTOM_FIELD = "rollmaster_processed".freeze end require_relative "lib/rollmaster/engine" @@ -26,9 +27,19 @@ module ::Rollmaster # I don't think this is needed, but it doesn't hurt to be safe ::Rollmaster::DiceEngine.reset_context + register_post_custom_field_type(::Rollmaster::POST_CUSTOM_FIELD, :boolean) + on(:before_post_process_cooked) do |doc, post| ::Rollmaster::HandleCookedPostProcess.process(doc, post) if SiteSetting.rollmaster_enabled end + add_to_class(:post, :has_rolls?) { custom_fields[::Rollmaster::POST_CUSTOM_FIELD] || false } + add_to_class(:post, :rolls) { ::Rollmaster::Roll.where(post_id: id) if has_rolls? } + + add_to_serializer(:post, :has_rolls?) { object.has_rolls? } + add_to_serializer(:post, :rolls) do + (object.rolls || []).map { |roll| ::Rollmaster::RollSerializer.new(roll, root: false) } + end + # TODO: consider :chat_message_processed as well end diff --git a/spec/integration/bbcode_spec.rb b/spec/integration/bbcode_spec.rb index 75a3e14..80d5053 100644 --- a/spec/integration/bbcode_spec.rb +++ b/spec/integration/bbcode_spec.rb @@ -19,6 +19,7 @@ expect(roll).not_to be_nil expect(roll.post_id).to eq(post.id) expect(roll.raw).to eq("2d6") + expect(post.custom_fields[::Rollmaster::POST_CUSTOM_FIELD]).to be(true) expect(cpp.html).to include("data-roll-id=\"#{roll.id}\"") end From efa6bcd7909babfc72d16add1c5100d87caac58c Mon Sep 17 00:00:00 2001 From: Alteras1 <42795314+Alteras1@users.noreply.github.com.> Date: Mon, 13 Oct 2025 17:11:04 -0700 Subject: [PATCH 02/15] Add blockquote formatting for roll results in posts --- .../discourse/initializers/decorate-post.js | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/assets/javascripts/discourse/initializers/decorate-post.js b/assets/javascripts/discourse/initializers/decorate-post.js index 6eb3aba..9ad6c55 100644 --- a/assets/javascripts/discourse/initializers/decorate-post.js +++ b/assets/javascripts/discourse/initializers/decorate-post.js @@ -1,4 +1,5 @@ import { withPluginApi } from "discourse/lib/plugin-api"; +import { applyValueTransformer } from "discourse/lib/transformer"; import RollsPostMenuButton from "../components/rolls-post-menu-button"; function decorateCookedElement(el, helper) { @@ -11,12 +12,36 @@ function decorateCookedElement(el, helper) { ".bb-rollmaster[data-notation][data-roll-id]" ); console.log(rollElems, rolls); + + rollElems.forEach((rollElem) => { + const rollId = rollElem.getAttribute("data-roll-id"); + const roll = rolls.find((r) => r.id.toString() === rollId); + if (!roll) { + return; + } + // todo: add blockquote around roll result + let htmlString = `
${roll.result}
`; + + htmlString = applyValueTransformer( + "rollmaster-cooked-roll-result", + htmlString, + { roll, post: helper.getModel(), helper, element: rollElem } + ); + rollElem.outerHTML = htmlString; + }); } export default { name: "rollmaster-decorate-post", initialize() { withPluginApi((api) => { + api.addValueTransformerName("rollmaster-cooked-roll-result"); api.decorateCookedElement(decorateCookedElement); api.registerValueTransformer( From 1afccc4a37129bf663852269bacae7f6ed5d8f28 Mon Sep 17 00:00:00 2001 From: Alteras1 <42795314+Alteras1@users.noreply.github.com.> Date: Tue, 14 Oct 2025 14:41:29 -0700 Subject: [PATCH 03/15] Add description field to rollmaster rolls and update related components --- app/model/rollmaster/roll.rb | 1 + .../discourse/initializers/decorate-post.js | 28 +++++++++++++------ .../rollmaster-transformer.js | 11 ++++++++ .../lib/discourse-markdown/bbcode.js | 7 +++-- assets/stylesheets/common/index.scss | 20 +++++++++++++ ...0925161854_add_desc_to_rollmaster_rolls.rb | 7 +++++ lib/rollmaster/handle_cooked_post_process.rb | 11 ++++++-- 7 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js create mode 100644 db/migrate/20250925161854_add_desc_to_rollmaster_rolls.rb diff --git a/app/model/rollmaster/roll.rb b/app/model/rollmaster/roll.rb index 2396146..326a701 100644 --- a/app/model/rollmaster/roll.rb +++ b/app/model/rollmaster/roll.rb @@ -22,6 +22,7 @@ class Roll < ActiveRecord::Base # raw :string # notation :string # result :string +# desc :string # created_at :datetime not null # updated_at :datetime not null # diff --git a/assets/javascripts/discourse/initializers/decorate-post.js b/assets/javascripts/discourse/initializers/decorate-post.js index 9ad6c55..c7205df 100644 --- a/assets/javascripts/discourse/initializers/decorate-post.js +++ b/assets/javascripts/discourse/initializers/decorate-post.js @@ -1,4 +1,6 @@ +import icon from "discourse/helpers/d-icon"; import { withPluginApi } from "discourse/lib/plugin-api"; +import { sanitize } from "discourse/lib/text"; import { applyValueTransformer } from "discourse/lib/transformer"; import RollsPostMenuButton from "../components/rolls-post-menu-button"; @@ -11,7 +13,6 @@ function decorateCookedElement(el, helper) { const rollElems = el.querySelectorAll( ".bb-rollmaster[data-notation][data-roll-id]" ); - console.log(rollElems, rolls); rollElems.forEach((rollElem) => { const rollId = rollElem.getAttribute("data-roll-id"); @@ -19,14 +20,24 @@ function decorateCookedElement(el, helper) { if (!roll) { return; } - // todo: add blockquote around roll result + let htmlString = `
${roll.result}
`; + dir="auto" + class="bb-rollmaster-result" + data-roll-id="${roll.id}" + data-desc="${sanitize(roll.desc || "")}" + data-notation="${sanitize(roll.notation)}" + data-result="${sanitize(roll.result)}" +> +

+ + ${icon("rollmaster-dices")} + ${sanitize(roll.desc || "Roll")}: + + ${sanitize(roll.notation)} +

+

${roll.result}

+`; htmlString = applyValueTransformer( "rollmaster-cooked-roll-result", @@ -41,7 +52,6 @@ export default { name: "rollmaster-decorate-post", initialize() { withPluginApi((api) => { - api.addValueTransformerName("rollmaster-cooked-roll-result"); api.decorateCookedElement(decorateCookedElement); api.registerValueTransformer( diff --git a/assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js b/assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js new file mode 100644 index 0000000..2073464 --- /dev/null +++ b/assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js @@ -0,0 +1,11 @@ +import { withPluginApi } from "discourse/lib/plugin-api"; + +export default { + before: "freeze-valid-transformers", + + initialize() { + withPluginApi((api) => { + api.addValueTransformerName("rollmaster-cooked-roll-result"); + }); + }, +}; diff --git a/assets/javascripts/lib/discourse-markdown/bbcode.js b/assets/javascripts/lib/discourse-markdown/bbcode.js index 4afe472..5678e22 100644 --- a/assets/javascripts/lib/discourse-markdown/bbcode.js +++ b/assets/javascripts/lib/discourse-markdown/bbcode.js @@ -1,14 +1,17 @@ import { i18n } from "discourse-i18n"; const ROLL_CLASS = "bb-rollmaster"; -const DATA_DICE = "data-notation"; function applyRollAttrs(state, token, attrs, content) { token.attrs = [ ["class", ROLL_CLASS], - [DATA_DICE, content], + ["data-notation", content], ]; + if (attrs._default) { + token.attrs.push(["data-desc", attrs._default]); + } + if (content) { token = state.push("text", "", 0); token.content = i18n("rollmaster.bbcode.placeholder") + content; diff --git a/assets/stylesheets/common/index.scss b/assets/stylesheets/common/index.scss index 999aa47..bfb3ac2 100644 --- a/assets/stylesheets/common/index.scss +++ b/assets/stylesheets/common/index.scss @@ -30,3 +30,23 @@ animation: rotate-forever 1s infinite linear; color: var(--primary-low-mid); } + +.bb-rollmaster-result { + .bb-rollmaster-title { + color: var(--primary-high-or-secondary-low); + margin-bottom: 0.25em; + font-size: var(--font-down-1); + + .d-icon { + display: inline-block; + font-size: var(--font-0-rem); + margin: auto 0; + margin-right: 0.25em; + } + } + + .bb-rollmaster-results { + margin-top: 0.25em; + font-family: var(--d-font-family--monospace); + } +} diff --git a/db/migrate/20250925161854_add_desc_to_rollmaster_rolls.rb b/db/migrate/20250925161854_add_desc_to_rollmaster_rolls.rb new file mode 100644 index 0000000..1e903d3 --- /dev/null +++ b/db/migrate/20250925161854_add_desc_to_rollmaster_rolls.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddDescToRollmasterRolls < ActiveRecord::Migration[7.2] + def change + add_column :rollmaster_rolls, :desc, :string + end +end diff --git a/lib/rollmaster/handle_cooked_post_process.rb b/lib/rollmaster/handle_cooked_post_process.rb index b20d2a9..5fee639 100644 --- a/lib/rollmaster/handle_cooked_post_process.rb +++ b/lib/rollmaster/handle_cooked_post_process.rb @@ -15,6 +15,7 @@ def self.process(doc, post) .css(SELECTOR_QUERY) .each do |roll_element| original_notation = roll_element.attribute("data-notation").value + desc = roll_element.attribute("data-desc")&.value next if original_notation.blank? @@ -22,9 +23,9 @@ def self.process(doc, post) .split(/\n/) .each do |notation| if notation.strip.empty? - roll_elements << { raw: "", dom: roll_element } # let us keep empty lines + roll_elements << { raw: "", dom: roll_element, desc: desc } # let us keep empty lines else - roll_elements << { raw: notation, dom: roll_element } + roll_elements << { raw: notation, dom: roll_element, desc: desc } end end roll_element.content = "" # clear the original notation @@ -101,7 +102,10 @@ def self.save_rolls(rolls, post) .each do |roll| if roll[:id] existing_roll = Rollmaster::Roll.find(roll[:id]) - existing_roll.update!(raw: roll[:raw], notation: roll[:formatted]) + if existing_roll.raw != roll[:raw] || existing_roll.notation != roll[:formatted] || + existing_roll.desc != roll[:desc] + existing_roll.update!(raw: roll[:raw], notation: roll[:formatted], desc: roll[:desc]) + end else new_roll = Rollmaster::Roll.create!( @@ -109,6 +113,7 @@ def self.save_rolls(rolls, post) raw: roll[:raw], notation: roll[:formatted], result: roll[:result], + desc: roll[:desc], ) roll[:id] = new_roll.id end From 70d653a4b70dc13d62e9a549726d0c2beab2205c Mon Sep 17 00:00:00 2001 From: Alteras1 Date: Sat, 1 Aug 2026 20:00:31 -0700 Subject: [PATCH 04/15] Initial pass for rolls post menu & history --- app/serializers/rollmaster/roll_serializer.rb | 2 +- .../components/rolls-post-menu-button.gjs | 94 ++++++++++++- .../rollmaster-roll-changes.gjs | 88 ++++++++++++ assets/stylesheets/common/index.scss | 132 ++++++++++++++++++ config/locales/client.en.yml | 16 ++- lib/rollmaster/handle_cooked_post_process.rb | 6 +- lib/rollmaster/roll_history.rb | 80 +++++++++++ plugin.rb | 13 +- spec/integration/bbcode_spec.rb | 52 +++++-- spec/requests/posts_controller_spec.rb | 52 +++++++ .../page_objects/modals/roll_history.rb | 30 ++++ .../modals/rollmaster_post_history.rb | 29 ++++ .../page_objects/pages/rollmaster_topic.rb | 15 ++ spec/system/post_history_rolls_spec.rb | 56 ++++++++ spec/system/roll_history_spec.rb | 44 ++++++ 15 files changed, 686 insertions(+), 23 deletions(-) create mode 100644 assets/javascripts/discourse/connectors/post-revisions/rollmaster-roll-changes.gjs create mode 100644 lib/rollmaster/roll_history.rb create mode 100644 spec/requests/posts_controller_spec.rb create mode 100644 spec/system/page_objects/modals/roll_history.rb create mode 100644 spec/system/page_objects/modals/rollmaster_post_history.rb create mode 100644 spec/system/page_objects/pages/rollmaster_topic.rb create mode 100644 spec/system/post_history_rolls_spec.rb create mode 100644 spec/system/roll_history_spec.rb diff --git a/app/serializers/rollmaster/roll_serializer.rb b/app/serializers/rollmaster/roll_serializer.rb index 5b520a6..4f959df 100644 --- a/app/serializers/rollmaster/roll_serializer.rb +++ b/app/serializers/rollmaster/roll_serializer.rb @@ -2,6 +2,6 @@ module ::Rollmaster class RollSerializer < ApplicationSerializer - attributes :id, :post_id, :raw, :notation, :result, :created_at, :updated_at + attributes :id, :post_id, :raw, :notation, :result, :desc, :created_at, :updated_at end end diff --git a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs index 04a3531..1e3472a 100644 --- a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs +++ b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs @@ -1,23 +1,49 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; +import { fn } from "@ember/helper"; import { action } from "@ember/object"; import DButton from "discourse/components/d-button"; -import { i18n } from "discourse-i18n"; import DModal from "discourse/components/d-modal"; -import { fn } from "@ember/helper"; +import { i18n } from "discourse-i18n"; export default class RollsPostMenuButton extends Component { static hidden() { return false; } - @tracked rolls = this.args.post.rolls || []; @tracked modalIsOpen = false; + get currentRollIds() { + return new Set( + (this.args.post.current_roll_ids || []).map((rollId) => Number(rollId)) + ); + } + + get rolls() { + return [...(this.args.post.rolls || [])] + .sort( + (left, right) => new Date(right.created_at) - new Date(left.created_at) + ) + .map((roll) => ({ + ...roll, + formattedCreatedAt: this.formatTimestamp(roll.created_at), + isCurrent: this.currentRollIds.has(Number(roll.id)), + })); + } + + formatTimestamp(timestamp) { + if (!timestamp) { + return ""; + } + + return new Intl.DateTimeFormat(undefined, { + dateStyle: "medium", + timeStyle: "short", + }).format(new Date(timestamp)); + } + @action showRolls() { - console.log("Rolls:", this.rolls); - // Implement the logic to show rolls, e.g., open a modal or dropdown this.modalIsOpen = true; } @@ -32,10 +58,66 @@ export default class RollsPostMenuButton extends Component { {{#if this.modalIsOpen}} - hello world +
+ {{#each this.rolls as |roll|}} +
+
+ + {{if + roll.isCurrent + (i18n "rollmaster.post.current") + (i18n "rollmaster.post.historical") + }} + + +
+ + {{#if roll.desc}} +

+ {{roll.desc}} +

+ {{/if}} + +
+
+
{{i18n "rollmaster.post.notation"}}
+
{{roll.notation}}
+
+
+
{{i18n "rollmaster.post.result"}}
+
{{roll.result}}
+
+
+
+ {{else}} +

+ {{i18n "rollmaster.post.empty"}} +

+ {{/each}} +
{{/if}} diff --git a/assets/javascripts/discourse/connectors/post-revisions/rollmaster-roll-changes.gjs b/assets/javascripts/discourse/connectors/post-revisions/rollmaster-roll-changes.gjs new file mode 100644 index 0000000..e4e42ab --- /dev/null +++ b/assets/javascripts/discourse/connectors/post-revisions/rollmaster-roll-changes.gjs @@ -0,0 +1,88 @@ +import Component from "@glimmer/component"; +import { or } from "discourse/truth-helpers"; +import { i18n } from "discourse-i18n"; + +export default class RollmasterRollChanges extends Component { + static shouldRender(outletArgs) { + return ( + outletArgs.model.roll_changes?.previous?.length || + outletArgs.model.roll_changes?.current?.length + ); + } + + get previousRolls() { + return this.args.outletArgs.model.roll_changes?.previous || []; + } + + get currentRolls() { + return this.args.outletArgs.model.roll_changes?.current || []; + } + + +} diff --git a/assets/stylesheets/common/index.scss b/assets/stylesheets/common/index.scss index bfb3ac2..06035e1 100644 --- a/assets/stylesheets/common/index.scss +++ b/assets/stylesheets/common/index.scss @@ -12,6 +12,7 @@ rgb(140, 140, 140) ); color: var(--success-mild, --success-medium); + &:has(~ .rollmaster-spinner) { color: var(--primary-low-mid); } @@ -45,6 +46,137 @@ } } + .rollmaster-roll-history-modal { + .d-modal__body { + max-height: min(70vh, 40rem); + overflow-y: auto; + } + } + + .rollmaster-roll-history { + display: flex; + flex-direction: column; + gap: 1rem; + } + + .rollmaster-roll-history__entry { + border: 1px solid var(--primary-low); + border-radius: 0.5rem; + padding: 0.875rem; + background: var(--secondary); + } + + .rollmaster-roll-history__entry-header { + display: flex; + justify-content: space-between; + gap: 0.75rem; + align-items: center; + margin-bottom: 0.5rem; + } + + .rollmaster-roll-history__status { + display: inline-flex; + align-items: center; + border-radius: 999px; + padding: 0.125rem 0.5rem; + font-size: var(--font-down-1); + font-weight: var(--font-weight-semibold); + } + + .rollmaster-roll-history__status--current { + background: var(--success-low); + color: var(--success); + } + + .rollmaster-roll-history__status--historical { + background: var(--primary-low); + color: var(--primary-high); + } + + .rollmaster-roll-history__timestamp { + color: var(--primary-medium); + font-size: var(--font-down-1); + } + + .rollmaster-roll-history__description { + margin: 0 0 0.75rem; + color: var(--primary-high); + } + + .rollmaster-roll-history__details { + display: grid; + gap: 0.75rem; + margin: 0; + } + + .rollmaster-roll-history__detail { + display: grid; + gap: 0.125rem; + + dt { + color: var(--primary-medium); + font-size: var(--font-down-1); + } + + dd { + margin: 0; + font-family: var(--d-font-family--monospace); + } + } + + .rollmaster-roll-history__empty { + margin: 0; + color: var(--primary-medium); + } + + .rollmaster-revision-rolls { + display: grid; + grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); + gap: 0.75rem; + align-items: start; + + .revision-content { + min-width: 0; + } + } + + .rollmaster-revision-rolls__heading { + margin: 0 0 0.5rem; + color: var(--primary-medium); + font-size: var(--font-down-1); + font-weight: var(--font-weight-semibold); + } + + .rollmaster-revision-rolls__list { + margin: 0; + padding-left: 1rem; + } + + .rollmaster-revision-rolls__entry { + margin-bottom: 0.25rem; + font-family: var(--d-font-family--monospace); + } + + .rollmaster-revision-rolls__description { + font-family: var(--d-font-family); + font-weight: var(--font-weight-semibold); + } + + .rollmaster-revision-rolls__notation, + .rollmaster-revision-rolls__result { + display: inline; + } + + .rollmaster-revision-rolls__result::before { + content: ": "; + } + + .rollmaster-revision-rolls__empty, + .rollmaster-revision-rolls__arrow { + margin: 0; + color: var(--primary-medium); + } + .bb-rollmaster-results { margin-top: 0.25em; font-family: var(--d-font-family--monospace); diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index eb7041c..87558cf 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -7,10 +7,18 @@ en: js: rollmaster: post: - title: "view rolls made in this post" + title: "View roll history" + current: "Current" + historical: "Historical" + notation: "Notation" + result: "Result" + empty: "No rolls have been saved for this post." + revisions: + title: "Rolls" + empty: "No rolls" bbcode: placeholder: "Rolling: " validator: - loading: "validating roll notation..." - success: "all roll notations valid" - error: "invalid roll notation found" + loading: "Validating roll notation..." + success: "All roll notations are valid" + error: "Invalid roll notation found" diff --git a/lib/rollmaster/handle_cooked_post_process.rb b/lib/rollmaster/handle_cooked_post_process.rb index 5fee639..876cba0 100644 --- a/lib/rollmaster/handle_cooked_post_process.rb +++ b/lib/rollmaster/handle_cooked_post_process.rb @@ -38,7 +38,7 @@ def self.process(doc, post) notation = element[:raw] next if notation.blank? - element.merge!(process_roll(notation)) + element.merge!(process_roll(notation, post)) end # { raw, dom, formatted, result, error, id }[] @@ -65,7 +65,7 @@ def self.process(doc, post) true end - def self.process_roll(notation) + def self.process_roll(notation, post) begin formatted = Rollmaster::DiceEngine.format_notation(notation).first final = Rollmaster::DiceEngine.roll(notation).first @@ -77,7 +77,7 @@ def self.process_roll(notation) end def self.match_rolls(rolls, post) - existing_rolls = Rollmaster::Roll.where(post_id: post.id).to_a + existing_rolls = Rollmaster::RollHistory.current_rolls(post) return if existing_rolls.empty? rolls diff --git a/lib/rollmaster/roll_history.rb b/lib/rollmaster/roll_history.rb new file mode 100644 index 0000000..e2f818f --- /dev/null +++ b/lib/rollmaster/roll_history.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +module ::Rollmaster + class RollHistory + SELECTOR_QUERY = ".bb-rollmaster[data-roll-id]".freeze + + def self.current_roll_ids(cooked) + roll_entries(cooked).map { |entry| entry[:id] } + end + + def self.current_rolls(post) + current_ids = current_roll_ids(cooked_for_matching(post)) + return [] if current_ids.empty? + + ::Rollmaster::Roll.where(id: current_ids).to_a + end + + def self.cooked_for_matching(post) + return post.cooked if !post.id? || !post.persisted? + + previous_cooked = post.attribute_before_last_save("cooked") + return previous_cooked if previous_cooked.present? + + post.class.unscoped.where(id: post.id).pick(:cooked) + end + + def self.roll_changes(previous_cooked, current_cooked) + previous_rolls = roll_entries(previous_cooked) + current_rolls = roll_entries(current_cooked) + + return if previous_rolls.blank? && current_rolls.blank? + return if previous_rolls == current_rolls + + { previous: previous_rolls, current: current_rolls } + end + + def self.roll_entries(cooked) + roll_snapshots = parse_roll_snapshots(cooked) + return [] if roll_snapshots.empty? + + results_by_id = + ::Rollmaster::Roll + .where(id: roll_snapshots.map { |entry| entry[:id] }) + .pluck(:id, :result) + .to_h + + roll_snapshots.filter_map do |entry| + result = results_by_id[entry[:id]] + next if result.blank? + + entry.merge(result: result) + end + end + + def self.parse_roll_snapshots(cooked) + return [] if cooked.blank? + + Nokogiri::HTML5 + .fragment(cooked) + .css(SELECTOR_QUERY) + .flat_map do |element| + roll_ids = split_roll_ids(element["data-roll-id"]) + notations = split_roll_notations(element["data-notation"]) + desc = element["data-desc"].presence + + roll_ids.map.with_index do |roll_id, index| + { id: roll_id, notation: notations[index] || notations.last.to_s, desc: desc } + end + end + end + + def self.split_roll_ids(value) + value.to_s.split(",").map(&:strip).reject(&:blank?).map(&:to_i) + end + + def self.split_roll_notations(value) + value.to_s.split("\n").map(&:strip).reject(&:blank?) + end + end +end diff --git a/plugin.rb b/plugin.rb index 2406d11..9bfb2db 100644 --- a/plugin.rb +++ b/plugin.rb @@ -18,6 +18,7 @@ module ::Rollmaster end require_relative "lib/rollmaster/engine" +require_relative "lib/rollmaster/roll_history" after_initialize do # Code which should run after Rails has finished booting @@ -34,12 +35,22 @@ module ::Rollmaster end add_to_class(:post, :has_rolls?) { custom_fields[::Rollmaster::POST_CUSTOM_FIELD] || false } - add_to_class(:post, :rolls) { ::Rollmaster::Roll.where(post_id: id) if has_rolls? } + add_to_class(:post, :rolls) do + ::Rollmaster::Roll.where(post_id: id).order(created_at: :desc, id: :desc) if has_rolls? + end + add_to_class(:post, :current_roll_ids) { ::Rollmaster::RollHistory.current_roll_ids(cooked) } add_to_serializer(:post, :has_rolls?) { object.has_rolls? } + add_to_serializer(:post, :current_roll_ids) { object.current_roll_ids } add_to_serializer(:post, :rolls) do (object.rolls || []).map { |roll| ::Rollmaster::RollSerializer.new(roll, root: false) } end + add_to_serializer( + :post_revision, + :roll_changes, + include_condition: -> { roll_changes.present? }, + ) { ::Rollmaster::RollHistory.roll_changes(previous["cooked"], current["cooked"]) } + # TODO: consider :chat_message_processed as well end diff --git a/spec/integration/bbcode_spec.rb b/spec/integration/bbcode_spec.rb index 80d5053..6ff43a4 100644 --- a/spec/integration/bbcode_spec.rb +++ b/spec/integration/bbcode_spec.rb @@ -11,8 +11,7 @@ [roll]2d6[/roll] MD post.save - cpp = CookedPostProcessor.new(post) - cpp.post_process + cpp = process_post(post) roll = ::Rollmaster::Roll.find_by(post_id: post.id) @@ -31,8 +30,7 @@ [roll]4d6kh3[/roll] MD post.save - cpp = CookedPostProcessor.new(post) - cpp.post_process + cpp = process_post(post) rolls = ::Rollmaster::Roll.where(post_id: post.id).to_a @@ -46,8 +44,7 @@ Initial roll: [roll]1d6[/roll] MD post.save - cpp = CookedPostProcessor.new(post) - cpp.post_process + cpp = process_post(post) initial_roll = ::Rollmaster::Roll.find_by(post_id: post.id) expect(initial_roll).not_to be_nil @@ -60,8 +57,7 @@ [roll]1d4+1[/roll] MD post.save - cpp = CookedPostProcessor.new(post) - cpp.post_process + cpp = process_post(post) rolls = ::Rollmaster::Roll.where(post_id: post.id).to_a expect(rolls.size).to eq(2) @@ -69,4 +65,44 @@ expect(initial_roll.id).in?(rolls.map(&:id)) rolls.each { |roll| expect(cpp.html).to include("data-roll-id=\"#{roll.id}\"") } end + + it "keeps prior rolls in history when a later edit rerolls the same notation" do + post = Fabricate(:post, raw: <<~MD) + Initial roll: [roll]1d6[/roll] + MD + post.save + + process_post(post) + + initial_roll = ::Rollmaster::Roll.find_by!(post_id: post.id, raw: "1d6") + + post.raw = <<~MD + Updated roll: [roll]1d8[/roll] + MD + post.save + + process_post(post) + + post.raw = <<~MD + Back to the original notation: [roll]1d6[/roll] + MD + post.save + + rerolled_cpp = process_post(post) + + rolls = ::Rollmaster::Roll.where(post_id: post.id).order(:created_at, :id) + rerolled_roll = rolls.last + + expect(rolls.map(&:raw)).to eq(%w[1d6 1d8 1d6]) + expect(rerolled_roll.id).not_to eq(initial_roll.id) + expect(post.reload.current_roll_ids).to eq([rerolled_roll.id]) + expect(rerolled_cpp.html).to include("data-roll-id=\"#{rerolled_roll.id}\"") + end + + def process_post(post) + cpp = CookedPostProcessor.new(post) + cpp.post_process + post.update_column(:cooked, cpp.html) + cpp + end end diff --git a/spec/requests/posts_controller_spec.rb b/spec/requests/posts_controller_spec.rb new file mode 100644 index 0000000..dc875dc --- /dev/null +++ b/spec/requests/posts_controller_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +RSpec.describe PostsController, type: :request do + fab!(:user) + fab!(:topic) { Fabricate(:topic, user: user) } + + let(:post) { Fabricate(:post, topic: topic, user: user, raw: "Opening roll: [roll]1d6[/roll]") } + + before do + enable_current_plugin + SiteSetting.rollmaster_enabled = true + SiteSetting.editing_grace_period = 0 + + process_initial_roll_state(post) + revise_post(post, "Changed roll: [roll]1d8[/roll]") + revise_post(post, "Back again: [roll]1d6[/roll]") + + sign_in(user) + end + + describe "#latest_revision" do + it "includes roll changes for the compared revisions" do + get "/posts/#{post.id}/revisions/latest.json" + + expect(response).to have_http_status(:ok) + expect( + response.parsed_body.dig("roll_changes", "previous").map { |entry| entry["notation"] }, + ).to eq(["1d8"]) + expect( + response.parsed_body.dig("roll_changes", "current").map { |entry| entry["notation"] }, + ).to eq(["1d6"]) + expect(response.parsed_body.dig("roll_changes", "current").first["id"]).not_to eq( + response.parsed_body.dig("roll_changes", "previous").first["id"], + ) + end + end + + def process_initial_roll_state(post) + cpp = CookedPostProcessor.new(post) + cpp.post_process + post.update_column(:cooked, cpp.html) + post.reload + end + + def revise_post(post, raw) + PostRevisor.new(post).revise!(user, { raw: raw, edit_reason: "reroll" }) + cpp = CookedPostProcessor.new(post) + cpp.post_process + post.update_column(:cooked, cpp.html) + post.reload + end +end diff --git a/spec/system/page_objects/modals/roll_history.rb b/spec/system/page_objects/modals/roll_history.rb new file mode 100644 index 0000000..a3e1b6a --- /dev/null +++ b/spec/system/page_objects/modals/roll_history.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module PageObjects + module Modals + class RollHistory < PageObjects::Modals::Base + MODAL_SELECTOR = ".rollmaster-roll-history-modal" + + def row_count + rows.size + end + + def has_entry?(notation:, status:) + entry_count(notation: notation, status: status).positive? + end + + def entry_count(notation:, status:) + rows.count do |row| + row_text = row.text + row_text.include?(notation) && row_text.include?(status) + end + end + + private + + def rows + body.all("[data-test-roll-history-row]") + end + end + end +end diff --git a/spec/system/page_objects/modals/rollmaster_post_history.rb b/spec/system/page_objects/modals/rollmaster_post_history.rb new file mode 100644 index 0000000..71faab5 --- /dev/null +++ b/spec/system/page_objects/modals/rollmaster_post_history.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +module PageObjects + module Modals + class RollmasterPostHistory < PageObjects::Modals::PostHistory + def previous_roll_entries + roll_entries("[data-test-roll-revision-previous]") + end + + def current_roll_entries + roll_entries("[data-test-roll-revision-current]") + end + + def has_previous_roll_entry?(notation) + previous_roll_entries.any? { |entry| entry.include?(notation) } + end + + def has_current_roll_entry?(notation) + current_roll_entries.any? { |entry| entry.include?(notation) } + end + + private + + def roll_entries(scope) + body.all("#{scope} .rollmaster-revision-rolls__entry").map(&:text) + end + end + end +end diff --git a/spec/system/page_objects/pages/rollmaster_topic.rb b/spec/system/page_objects/pages/rollmaster_topic.rb new file mode 100644 index 0000000..c276bac --- /dev/null +++ b/spec/system/page_objects/pages/rollmaster_topic.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module PageObjects + module Pages + class RollmasterTopic < PageObjects::Pages::Topic + def has_roll_history_button?(post) + within_post(post) { has_css?(".post-action-menu__view-rolls") } + end + + def open_roll_history(post) + within_post(post) { find(".post-action-menu__view-rolls").click } + end + end + end +end diff --git a/spec/system/post_history_rolls_spec.rb b/spec/system/post_history_rolls_spec.rb new file mode 100644 index 0000000..461115d --- /dev/null +++ b/spec/system/post_history_rolls_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +RSpec.describe "Post history rolls", type: :system do + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } + fab!(:topic) { Fabricate(:topic, user: user) } + + let(:post) { Fabricate(:post, topic: topic, user: user, raw: "Opening roll: [roll]1d6[/roll]") } + let(:post_history_modal) { PageObjects::Modals::RollmasterPostHistory.new } + let(:topic_page) { PageObjects::Pages::Topic.new } + + before do + enable_current_plugin + SiteSetting.rollmaster_enabled = true + SiteSetting.editing_grace_period = 0 + + process_initial_roll_state(post) + revise_post(post, "Changed roll: [roll]1d8[/roll]") + revise_post(post, "Back again: [roll]1d6[/roll]") + + sign_in(user) + end + + it "shows roll changes while the user browses post history" do + topic_page.visit_topic(topic) + page.refresh + + topic_page.open_post_history(post) + + expect(post_history_modal.current_roll_entries.size).to eq(1) + expect(post_history_modal.previous_roll_entries.size).to eq(1) + expect(post_history_modal).to have_current_roll_entry("1d6") + expect(post_history_modal).to have_previous_roll_entry("1d8") + + post_history_modal.click_previous_revision + + expect(post_history_modal.current_roll_entries.size).to eq(1) + expect(post_history_modal.previous_roll_entries.size).to eq(1) + expect(post_history_modal).to have_current_roll_entry("1d8") + expect(post_history_modal).to have_previous_roll_entry("1d6") + end + + def process_initial_roll_state(post) + cpp = CookedPostProcessor.new(post) + cpp.post_process + post.update_column(:cooked, cpp.html) + post.reload + end + + def revise_post(post, raw) + PostRevisor.new(post).revise!(user, { raw: raw, edit_reason: "reroll" }) + cpp = CookedPostProcessor.new(post) + cpp.post_process + post.update_column(:cooked, cpp.html) + post.reload + end +end diff --git a/spec/system/roll_history_spec.rb b/spec/system/roll_history_spec.rb new file mode 100644 index 0000000..e8fc2b0 --- /dev/null +++ b/spec/system/roll_history_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +RSpec.describe "Roll history", type: :system do + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } + fab!(:topic) + fab!(:post) { Fabricate(:post, topic: topic, user: user, raw: "Opening roll: [roll]1d6[/roll]") } + + let(:roll_history_modal) { PageObjects::Modals::RollHistory.new } + let(:topic_page) { PageObjects::Pages::RollmasterTopic.new } + + before do + enable_current_plugin + SiteSetting.rollmaster_enabled = true + + process_rolls(post) + process_rolls(post, "Changed roll: [roll]1d8[/roll]") + process_rolls(post, "Back again: [roll]1d6[/roll]") + + sign_in(user) + end + + it "lets the user review current and historical rolls from the post menu" do + topic_page.visit_topic(topic) + page.refresh + + expect(topic_page).to have_roll_history_button(post) + + topic_page.open_roll_history(post) + + expect(roll_history_modal).to be_open + expect(roll_history_modal.row_count).to eq(3) + expect(roll_history_modal.entry_count(notation: "1d6", status: "Current")).to eq(1) + expect(roll_history_modal.entry_count(notation: "1d6", status: "Historical")).to eq(1) + expect(roll_history_modal).to have_entry(notation: "1d8", status: "Historical") + end + + def process_rolls(post, raw = post.raw) + post.update!(raw: raw) + cpp = CookedPostProcessor.new(post) + cpp.post_process + post.update_column(:cooked, cpp.html) + post.reload + end +end From 6c1e3a03503759de265158775256505dd5f588f3 Mon Sep 17 00:00:00 2001 From: Alteras1 Date: Sun, 16 Aug 2026 00:25:26 +0000 Subject: [PATCH 05/15] DEV: disable rollmaster properly when setting is false --- .../lib/discourse-markdown/bbcode.js | 8 +++-- config/settings.yml | 2 +- spec/system/disabled_rolls_spec.rb | 31 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 spec/system/disabled_rolls_spec.rb diff --git a/assets/javascripts/lib/discourse-markdown/bbcode.js b/assets/javascripts/lib/discourse-markdown/bbcode.js index 5678e22..52f2a6b 100644 --- a/assets/javascripts/lib/discourse-markdown/bbcode.js +++ b/assets/javascripts/lib/discourse-markdown/bbcode.js @@ -45,11 +45,15 @@ const inlineRule = { export function setup(helper) { helper.allowList(["div.bb-rollmaster", "span.bb-rollmaster"]); - helper.registerOptions((opts) => { - opts.features["rollmaster"] = true; + helper.registerOptions((opts, siteSettings) => { + opts.features["rollmaster"] = !!siteSettings.rollmaster_enabled; }); helper.registerPlugin((md) => { + if (!md.options.discourse.features["rollmaster"]) { + return; + } + md.inline.bbcode.ruler.push("inline-roll", inlineRule); md.block.bbcode.ruler.push("block-roll", blockRule); }); diff --git a/config/settings.yml b/config/settings.yml index dd9f02c..1ea59d9 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -1,4 +1,4 @@ plugins: rollmaster_enabled: - default: false + default: true client: true diff --git a/spec/system/disabled_rolls_spec.rb b/spec/system/disabled_rolls_spec.rb new file mode 100644 index 0000000..5109190 --- /dev/null +++ b/spec/system/disabled_rolls_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +RSpec.describe "Disabled Rollmaster", type: :system do + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } + fab!(:topic) { Fabricate(:topic, user: user) } + fab!(:post) { Fabricate(:post, topic: topic, user: user) } + + let(:composer) { PageObjects::Components::Composer.new } + let(:topic_page) { PageObjects::Pages::Topic.new } + let(:roll_bbcode) { "[roll]2d6[/roll]" } + + before do + enable_current_plugin + SiteSetting.rollmaster_enabled = false + sign_in(user) + end + + it "preserves roll BBCode when posting" do + topic_page.visit_topic(topic) + topic_page.click_post_action_button(post, :reply) + + composer.fill_content(roll_bbcode) + composer.submit + + reply = topic.posts.order(:id).last + expect(reply.raw).to eq(roll_bbcode) + expect(topic_page).to have_post_content(post_number: reply.post_number, content: roll_bbcode) + expect(reply.cooked).not_to include('class="bb-rollmaster"') + expect(::Rollmaster::Roll.where(post_id: reply.id)).to be_empty + end +end From ecff6a9bc3654e4d68791d9569c70ed3b24d5172 Mon Sep 17 00:00:00 2001 From: Alteras1 Date: Sun, 16 Aug 2026 02:28:51 +0000 Subject: [PATCH 06/15] Remove multiline rolls and fix XSS simplify logic as well --- .../components/composer-valid-roll.gjs | 24 +++--- .../discourse/initializers/decorate-post.js | 57 ++++++++------ lib/rollmaster/handle_cooked_post_process.rb | 78 ++++++------------- lib/rollmaster/roll_history.rb | 41 +++------- spec/integration/bbcode_spec.rb | 64 +++++++++++++-- spec/system/roll_description_security_spec.rb | 32 ++++++++ 6 files changed, 164 insertions(+), 132 deletions(-) create mode 100644 spec/system/roll_description_security_spec.rb diff --git a/assets/javascripts/discourse/components/composer-valid-roll.gjs b/assets/javascripts/discourse/components/composer-valid-roll.gjs index 4acc4f3..8759b4b 100644 --- a/assets/javascripts/discourse/components/composer-valid-roll.gjs +++ b/assets/javascripts/discourse/components/composer-valid-roll.gjs @@ -88,21 +88,15 @@ export default class ComposerValidRoll extends Component { rollEls.forEach((el) => { /** @type string */ const notation = el.getAttribute(NOTE_ATTR); - const rolls = notation - .split("\n") - .map((r) => r.trim()) - .filter(Boolean); - rolls.forEach((roll) => { - try { - // TODO: Handle descriptions separately. parser won't be able to handle 2d20+4 // test - // see https://github.com/dice-roller/rpg-dice-roller/issues/287 - rpgDiceRoller.Parser.parse(roll); - } catch (err) { - this.errors.push(err); - // eslint-disable-next-line no-console - console.warn("Rollmaster: Error parsing notation", roll, err); - } - }); + try { + // TODO: Handle descriptions separately. parser won't be able to handle 2d20+4 // test + // see https://github.com/dice-roller/rpg-dice-roller/issues/287 + rpgDiceRoller.Parser.parse(notation); + } catch (err) { + this.errors.push(err); + // eslint-disable-next-line no-console + console.warn("Rollmaster: Error parsing notation", notation, err); + } }); } diff --git a/assets/javascripts/discourse/initializers/decorate-post.js b/assets/javascripts/discourse/initializers/decorate-post.js index c7205df..8c1e924 100644 --- a/assets/javascripts/discourse/initializers/decorate-post.js +++ b/assets/javascripts/discourse/initializers/decorate-post.js @@ -1,9 +1,40 @@ -import icon from "discourse/helpers/d-icon"; +import { iconElement } from "discourse/lib/icon-library"; import { withPluginApi } from "discourse/lib/plugin-api"; -import { sanitize } from "discourse/lib/text"; import { applyValueTransformer } from "discourse/lib/transformer"; import RollsPostMenuButton from "../components/rolls-post-menu-button"; +function rollResultElement(roll) { + const result = document.createElement("blockquote"); + result.dir = "auto"; + result.className = "bb-rollmaster-result"; + result.dataset.rollId = roll.id; + result.dataset.desc = roll.desc || ""; + result.dataset.notation = roll.notation; + result.dataset.result = roll.result; + + const title = document.createElement("p"); + title.className = "bb-rollmaster-title"; + + const description = document.createElement("span"); + description.className = "bb-rollmaster-description"; + description.append(iconElement("rollmaster-dices")); + description.append(` ${roll.desc || "Roll"}:`); + title.append(description); + + const notation = document.createElement("span"); + notation.className = "bb-rollmaster-notation"; + notation.textContent = roll.notation; + title.append(notation); + result.append(title); + + const rollResult = document.createElement("p"); + rollResult.className = "bb-rollmaster-results"; + rollResult.textContent = roll.result; + result.append(rollResult); + + return result; +} + function decorateCookedElement(el, helper) { if (!helper?.getModel()?.has_rolls) { return; @@ -21,27 +52,9 @@ function decorateCookedElement(el, helper) { return; } - let htmlString = `
-

- - ${icon("rollmaster-dices")} - ${sanitize(roll.desc || "Roll")}: - - ${sanitize(roll.notation)} -

-

${roll.result}

-
`; - - htmlString = applyValueTransformer( + const htmlString = applyValueTransformer( "rollmaster-cooked-roll-result", - htmlString, + rollResultElement(roll).outerHTML, { roll, post: helper.getModel(), helper, element: rollElem } ); rollElem.outerHTML = htmlString; diff --git a/lib/rollmaster/handle_cooked_post_process.rb b/lib/rollmaster/handle_cooked_post_process.rb index 876cba0..52344a0 100644 --- a/lib/rollmaster/handle_cooked_post_process.rb +++ b/lib/rollmaster/handle_cooked_post_process.rb @@ -7,60 +7,28 @@ class HandleCookedPostProcess def self.process(doc, post) # Add your processing logic here - # { raw, dom }[] - roll_elements = [] - - # parse the post content for rolls and flatten - doc - .css(SELECTOR_QUERY) - .each do |roll_element| - original_notation = roll_element.attribute("data-notation").value - desc = roll_element.attribute("data-desc")&.value - - next if original_notation.blank? - - original_notation - .split(/\n/) - .each do |notation| - if notation.strip.empty? - roll_elements << { raw: "", dom: roll_element, desc: desc } # let us keep empty lines - else - roll_elements << { raw: notation, dom: roll_element, desc: desc } - end - end - roll_element.content = "" # clear the original notation - end + roll_elements = + doc + .css(SELECTOR_QUERY) + .filter_map do |roll_element| + notation = roll_element.attribute("data-notation").value + next if notation.blank? + + roll_element.content = "" + { raw: notation, dom: roll_element, desc: roll_element.attribute("data-desc")&.value } + end return if roll_elements.empty? - # { raw, dom, formatted, result, error }[] - roll_elements.each do |element| - notation = element[:raw] - next if notation.blank? + roll_elements.each { |element| element.merge!(process_roll(element[:raw], post)) } - element.merge!(process_roll(notation, post)) - end - - # { raw, dom, formatted, result, error, id }[] match_rolls(roll_elements, post) if post.id? save_rolls(roll_elements, post) - roll_elements - .group_by { |e| e[:dom] } - .each do |dom, rolls| - content = - rolls.map do |e| - if e[:error] - e[:raw] - elsif e[:raw].empty? - "" - else - e[:raw] + ": " + e[:result] # TODO: consider decorating with spans - end - end - dom.content = CGI.unescapeHTML(content.join("\n")) - dom["data-roll-id"] = rolls.map { |e| e[:id] }.join(",") if rolls.any? { |e| e[:id] } - end + roll_elements.each do |roll| + roll[:dom].content = roll[:error] ? roll[:raw] : "#{roll[:raw]}: #{roll[:result]}" + roll[:dom]["data-roll-id"] = roll[:id] if roll[:id] + end true end @@ -77,20 +45,18 @@ def self.process_roll(notation, post) end def self.match_rolls(rolls, post) - existing_rolls = Rollmaster::RollHistory.current_rolls(post) + existing_rolls = Rollmaster::Roll.where(post_id: post.id).order(:created_at, :id).to_a return if existing_rolls.empty? rolls - .reject { |r| r[:raw].empty? || r[:error] } + .reject { |r| r[:error] } .each do |roll| - existing_roll_idx = - existing_rolls.index { |r| r.raw == roll[:raw] || r.notation == roll[:formatted] } - next if existing_roll_idx.nil? + existing_roll = existing_rolls.find { |existing| existing.notation == roll[:formatted] } + next if existing_roll.nil? - existing_roll = existing_rolls[existing_roll_idx] roll[:id] = existing_roll.id - roll[:result] = existing_roll.result # use existing roll result - existing_rolls.delete_at(existing_roll_idx) + roll[:result] = existing_roll.result + existing_rolls.delete(existing_roll) end end @@ -98,7 +64,7 @@ def self.save_rolls(rolls, post) post.custom_fields[::Rollmaster::POST_CUSTOM_FIELD] = true post.save_custom_fields rolls - .reject { |r| r[:raw].empty? || r[:error] } + .reject { |r| r[:error] } .each do |roll| if roll[:id] existing_roll = Rollmaster::Roll.find(roll[:id]) diff --git a/lib/rollmaster/roll_history.rb b/lib/rollmaster/roll_history.rb index e2f818f..06e1d2e 100644 --- a/lib/rollmaster/roll_history.rb +++ b/lib/rollmaster/roll_history.rb @@ -8,22 +8,6 @@ def self.current_roll_ids(cooked) roll_entries(cooked).map { |entry| entry[:id] } end - def self.current_rolls(post) - current_ids = current_roll_ids(cooked_for_matching(post)) - return [] if current_ids.empty? - - ::Rollmaster::Roll.where(id: current_ids).to_a - end - - def self.cooked_for_matching(post) - return post.cooked if !post.id? || !post.persisted? - - previous_cooked = post.attribute_before_last_save("cooked") - return previous_cooked if previous_cooked.present? - - post.class.unscoped.where(id: post.id).pick(:cooked) - end - def self.roll_changes(previous_cooked, current_cooked) previous_rolls = roll_entries(previous_cooked) current_rolls = roll_entries(current_cooked) @@ -58,23 +42,16 @@ def self.parse_roll_snapshots(cooked) Nokogiri::HTML5 .fragment(cooked) .css(SELECTOR_QUERY) - .flat_map do |element| - roll_ids = split_roll_ids(element["data-roll-id"]) - notations = split_roll_notations(element["data-notation"]) - desc = element["data-desc"].presence - - roll_ids.map.with_index do |roll_id, index| - { id: roll_id, notation: notations[index] || notations.last.to_s, desc: desc } - end + .filter_map do |element| + id = element["data-roll-id"].to_i + next if id.zero? + + { + id: id, + notation: element["data-notation"].to_s.strip, + desc: element["data-desc"].presence, + } end end - - def self.split_roll_ids(value) - value.to_s.split(",").map(&:strip).reject(&:blank?).map(&:to_i) - end - - def self.split_roll_notations(value) - value.to_s.split("\n").map(&:strip).reject(&:blank?) - end end end diff --git a/spec/integration/bbcode_spec.rb b/spec/integration/bbcode_spec.rb index 6ff43a4..edaafda 100644 --- a/spec/integration/bbcode_spec.rb +++ b/spec/integration/bbcode_spec.rb @@ -22,6 +22,18 @@ expect(cpp.html).to include("data-roll-id=\"#{roll.id}\"") end + it "renders markup-like dice comments as text" do + comment = '' + post = Fabricate(:post, raw: "[roll]1d6 // #{comment}[/roll]") + post.save + + cpp = process_post(post) + document = Nokogiri::HTML5.fragment(cpp.html) + + expect(document.css("img")).to be_empty + expect(document.text).to include(comment) + end + it "handles multiple [roll] BBCode in a single post" do post = Fabricate(:post, raw: <<~MD) Here are some rolls: @@ -39,6 +51,24 @@ rolls.each { |roll| expect(cpp.html).to include("data-roll-id=\"#{roll.id}\"") } end + it "preserves duplicate notation roll order across edits" do + post = Fabricate(:post, raw: '[roll="First"]1d6[/roll]' + "\n" + '[roll="Second"]1d6[/roll]') + process_post(post) + original_roll_ids = + ::Rollmaster::Roll.where(post_id: post.id).order(:created_at, :id).pluck(:id) + + post.raw = '[roll="Updated first"]1d6[/roll]' + "\n" + '[roll="Updated second"]1d6[/roll]' + post.save + cpp = process_post(post) + roll_ids = + Nokogiri::HTML5 + .fragment(cpp.html) + .css(".bb-rollmaster") + .map { |element| element["data-roll-id"].to_i } + + expect(roll_ids).to eq(original_roll_ids) + end + it "reuses existing rolls when a post is edited" do post = Fabricate(:post, raw: <<~MD) Initial roll: [roll]1d6[/roll] @@ -66,7 +96,29 @@ rolls.each { |roll| expect(cpp.html).to include("data-roll-id=\"#{roll.id}\"") } end - it "keeps prior rolls in history when a later edit rerolls the same notation" do + it "preserves the result when editing a roll description" do + user = Fabricate(:user) + post = Fabricate(:post, user: user, raw: '[roll="Initial description"]{4d6+2d8-3d30}d3[/roll]') + process_post(post) + initial_roll = ::Rollmaster::Roll.find_by!(post_id: post.id) + initial_result = initial_roll.result + + SiteSetting.editing_grace_period = 0 + PostRevisor.new(post).revise!( + user, + { raw: '[roll="Updated description"]{4d6+2d8-3d30}d3[/roll]', edit_reason: "update roll" }, + ) + + rolls = ::Rollmaster::Roll.where(post_id: post.id) + + expect(rolls).to contain_exactly(initial_roll) + expect(initial_roll.reload).to have_attributes( + desc: "Updated description", + result: initial_result, + ) + end + + it "reuses a roll when a later edit restores its formatted notation" do post = Fabricate(:post, raw: <<~MD) Initial roll: [roll]1d6[/roll] MD @@ -88,15 +140,13 @@ MD post.save - rerolled_cpp = process_post(post) + restored_cpp = process_post(post) rolls = ::Rollmaster::Roll.where(post_id: post.id).order(:created_at, :id) - rerolled_roll = rolls.last - expect(rolls.map(&:raw)).to eq(%w[1d6 1d8 1d6]) - expect(rerolled_roll.id).not_to eq(initial_roll.id) - expect(post.reload.current_roll_ids).to eq([rerolled_roll.id]) - expect(rerolled_cpp.html).to include("data-roll-id=\"#{rerolled_roll.id}\"") + expect(rolls.map(&:raw)).to eq(%w[1d6 1d8]) + expect(post.reload.current_roll_ids).to eq([initial_roll.id]) + expect(restored_cpp.html).to include("data-roll-id=\"#{initial_roll.id}\"") end def process_post(post) diff --git a/spec/system/roll_description_security_spec.rb b/spec/system/roll_description_security_spec.rb new file mode 100644 index 0000000..448486a --- /dev/null +++ b/spec/system/roll_description_security_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +RSpec.describe "Roll description rendering", type: :system do + fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } + fab!(:topic) { Fabricate(:topic, user: user) } + fab!(:post) do + Fabricate(:post, topic: topic, user: user, raw: '[roll=“x" onmouseover="alert(1)”]1d6[/roll]') + end + + let(:topic_page) { PageObjects::Pages::Topic.new } + + before do + enable_current_plugin + SiteSetting.rollmaster_enabled = true + process_rolls(post) + sign_in(user) + end + + it "does not turn a description into an HTML attribute" do + topic_page.visit_topic(topic) + + roll = page.find("#post_#{post.post_number} .bb-rollmaster-result") + expect(roll["data-desc"]).to eq('x" onmouseover="alert(1)') + expect(roll["onmouseover"]).to be_nil + end + + def process_rolls(post) + cpp = CookedPostProcessor.new(post) + cpp.post_process + post.update_column(:cooked, cpp.html) + end +end From 2a354c678b16a2b8dab179a4c8a0f1e2898b6553 Mon Sep 17 00:00:00 2001 From: Alteras1 Date: Sun, 16 Aug 2026 03:15:10 +0000 Subject: [PATCH 07/15] Update README --- README.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b0dc1c0..5ca2d63 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,24 @@ -# **Plugin Name** Plugin +# Rollmaster -**Plugin Summary** +A Discourse dice rolling plugin, with support for in-post roll history. Powered by the [RPG Dice Roller](https://dice-roller.github.io/documentation/) library. For more information, please see: **url to meta topic** + +--- + +This is a dice rolling plugin, using the amazing [RPG Dice Roller](https://dice-roller.github.io/documentation/) library. Users use the `[roll]` BBCode tag to roll in post. + +```bbcode +[roll]4d20[/roll] + +[roll="description of the roll"]4d10r<=3[/roll] +``` + +Notation of the dice rolls can be found at [RPG Dice Roller: Notation](https://dice-roller.github.io/documentation/guide/notation/), which supports modifiers (rerolls, fudge dice, fate dice, criticals, etc.), math (max/min, sorting, etc.), group rolls, and more. + +All rolls are saved and stored in the post history, and can be pulled up for each post, regardless of what the final cooked HTML displays. All rolls are reused in the same post, allowing users to freely edit the contents of their post (or fix their roll notation), while minimizing abuse. For example, suppose a user already rolled `1d20 = 14` using `[roll]1d20[/roll]` in their post. If the post is editted, and the `[roll]1d20[/roll]` remains the same, the plugin will reuse the previous `1d20 = 14` result. If the notation changes, a new roll is made. Changing the description of the roll won't create a reroll either. + +If multiple rolls are made in the same post, using the same notation, the plugin will create new rolls for each instance. Upon editing the post, the plugin will match and reuse the rolls in the order they appear in the post. + +All rolls made for a post are saved, and displayed in both the post history, and in a separate "Rolls" button in the post actions. This way, if a post has been modified, any user can see the history for any sign of abuse. Restoring an existing roll is as easy as reusing the notation. + From 388fc8850e1885d114e35a3291f6c30636545ce5 Mon Sep 17 00:00:00 2001 From: Alteras1 Date: Sun, 16 Aug 2026 06:13:41 +0000 Subject: [PATCH 08/15] Convert to output renders to Glimmer templates --- .../components/composer-valid-roll.gjs | 8 +- .../discourse/initializers/decorate-post.gjs | 76 +++++++++++++++++ .../discourse/initializers/decorate-post.js | 84 ------------------- .../discourse/initializers/preview.gjs | 68 +++++++++++++++ .../discourse/initializers/preview.js | 18 ---- config/locales/client.en.yml | 1 + 6 files changed, 149 insertions(+), 106 deletions(-) create mode 100644 assets/javascripts/discourse/initializers/decorate-post.gjs delete mode 100644 assets/javascripts/discourse/initializers/decorate-post.js create mode 100644 assets/javascripts/discourse/initializers/preview.gjs delete mode 100644 assets/javascripts/discourse/initializers/preview.js diff --git a/assets/javascripts/discourse/components/composer-valid-roll.gjs b/assets/javascripts/discourse/components/composer-valid-roll.gjs index 8759b4b..7b3837e 100644 --- a/assets/javascripts/discourse/components/composer-valid-roll.gjs +++ b/assets/javascripts/discourse/components/composer-valid-roll.gjs @@ -4,9 +4,9 @@ import { action } from "@ember/object"; import didInsert from "@ember/render-modifiers/modifiers/did-insert"; import didUpdate from "@ember/render-modifiers/modifiers/did-update"; import { debounce } from "@ember/runloop"; -import icon from "discourse/helpers/d-icon"; import loadscript from "discourse/lib/load-script"; import { cook } from "discourse/lib/text"; +import dIcon from "discourse/ui-kit/helpers/d-icon"; import { i18n } from "discourse-i18n"; /* global rpgDiceRoller */ @@ -117,14 +117,14 @@ export default class ComposerValidRoll extends Component { title={{this.title}} > {{#if this.hasRolls}} - {{icon "rollmaster-dices" class="svg-roll"}} + {{dIcon "rollmaster-dices" class="svg-roll"}} {{#if this.errors.length}} - {{icon "triangle-exclamation" class="roll__invalid"}} + {{dIcon "triangle-exclamation" class="roll__invalid"}} {{/if}} {{/if}} {{#if this.loading}} - {{icon "spinner" class="rollmaster-spinner"}} + {{dIcon "spinner" class="rollmaster-spinner"}} {{/if}} {{/if}} diff --git a/assets/javascripts/discourse/initializers/decorate-post.gjs b/assets/javascripts/discourse/initializers/decorate-post.gjs new file mode 100644 index 0000000..016df05 --- /dev/null +++ b/assets/javascripts/discourse/initializers/decorate-post.gjs @@ -0,0 +1,76 @@ +import { withPluginApi } from "discourse/lib/plugin-api"; +import dIcon from "discourse/ui-kit/helpers/d-icon"; +import { i18n } from "discourse-i18n"; +import RollsPostMenuButton from "../components/rolls-post-menu-button"; + +const RollResult = ; + +function decorateCookedElement(el, helper) { + if (!helper?.getModel()?.has_rolls) { + return; + } + + const rolls = helper.getModel().rolls; + const rollElems = el.querySelectorAll( + ".bb-rollmaster[data-notation][data-roll-id]" + ); + + rollElems.forEach((rollElem) => { + const rollId = rollElem.getAttribute("data-roll-id"); + const roll = rolls.find((r) => r.id.toString() === rollId); + if (!roll) { + return; + } + + roll.desc ??= i18n("rollmaster.bbcode.default"); + + // full replacement of the roll element with a glimmer component + const wrapper = document.createElement("div"); + wrapper.classList.add("bb-rollmaster-wrapper"); + helper.renderGlimmer( + wrapper, + + ); + rollElem.replaceWith(wrapper); + }); +} + +export default { + name: "rollmaster-decorate-post", + initialize() { + withPluginApi((api) => { + api.decorateCookedElement(decorateCookedElement); + + api.registerValueTransformer( + "post-menu-buttons", + ({ value: dag, context: { post } }) => { + if (!post.has_rolls) { + return; + } + dag.add("rollmaster-view-rolls", RollsPostMenuButton, { + before: ["delete", "showMore"], + after: ["bookmark", "edit"], + }); + } + ); + }); + }, +}; diff --git a/assets/javascripts/discourse/initializers/decorate-post.js b/assets/javascripts/discourse/initializers/decorate-post.js deleted file mode 100644 index 8c1e924..0000000 --- a/assets/javascripts/discourse/initializers/decorate-post.js +++ /dev/null @@ -1,84 +0,0 @@ -import { iconElement } from "discourse/lib/icon-library"; -import { withPluginApi } from "discourse/lib/plugin-api"; -import { applyValueTransformer } from "discourse/lib/transformer"; -import RollsPostMenuButton from "../components/rolls-post-menu-button"; - -function rollResultElement(roll) { - const result = document.createElement("blockquote"); - result.dir = "auto"; - result.className = "bb-rollmaster-result"; - result.dataset.rollId = roll.id; - result.dataset.desc = roll.desc || ""; - result.dataset.notation = roll.notation; - result.dataset.result = roll.result; - - const title = document.createElement("p"); - title.className = "bb-rollmaster-title"; - - const description = document.createElement("span"); - description.className = "bb-rollmaster-description"; - description.append(iconElement("rollmaster-dices")); - description.append(` ${roll.desc || "Roll"}:`); - title.append(description); - - const notation = document.createElement("span"); - notation.className = "bb-rollmaster-notation"; - notation.textContent = roll.notation; - title.append(notation); - result.append(title); - - const rollResult = document.createElement("p"); - rollResult.className = "bb-rollmaster-results"; - rollResult.textContent = roll.result; - result.append(rollResult); - - return result; -} - -function decorateCookedElement(el, helper) { - if (!helper?.getModel()?.has_rolls) { - return; - } - - const rolls = helper.getModel().rolls; - const rollElems = el.querySelectorAll( - ".bb-rollmaster[data-notation][data-roll-id]" - ); - - rollElems.forEach((rollElem) => { - const rollId = rollElem.getAttribute("data-roll-id"); - const roll = rolls.find((r) => r.id.toString() === rollId); - if (!roll) { - return; - } - - const htmlString = applyValueTransformer( - "rollmaster-cooked-roll-result", - rollResultElement(roll).outerHTML, - { roll, post: helper.getModel(), helper, element: rollElem } - ); - rollElem.outerHTML = htmlString; - }); -} - -export default { - name: "rollmaster-decorate-post", - initialize() { - withPluginApi((api) => { - api.decorateCookedElement(decorateCookedElement); - - api.registerValueTransformer( - "post-menu-buttons", - ({ value: dag, context: { post } }) => { - if (!post.has_rolls) { - return; - } - dag.add("rollmaster-view-rolls", RollsPostMenuButton, { - before: ["delete", "showMore"], - after: ["bookmark", "edit"], - }); - } - ); - }); - }, -}; diff --git a/assets/javascripts/discourse/initializers/preview.gjs b/assets/javascripts/discourse/initializers/preview.gjs new file mode 100644 index 0000000..6260594 --- /dev/null +++ b/assets/javascripts/discourse/initializers/preview.gjs @@ -0,0 +1,68 @@ +import { withPluginApi } from "discourse/lib/plugin-api"; +import dIcon from "discourse/ui-kit/helpers/d-icon"; +import { i18n } from "discourse-i18n"; +import ComposerValidRoll from "../components/composer-valid-roll"; + +const RollPreview = ; + +function initializeRollmasterPreview(api) { + const siteSettings = api.container.lookup("service:site-settings"); + if (!siteSettings.rollmaster_enabled) { + return; + } + + api.renderInOutlet("after-d-editor", ComposerValidRoll); + + api.decorateCookedElement((element, helper) => { + if (helper.getModel()) { + return; + } + // This is a preview, no model + + const rollElems = element.querySelectorAll( + ".bb-rollmaster[data-notation]:not([data-roll-id])" + ); + + rollElems.forEach((rollElem) => { + const notation = rollElem.dataset.notation; + if (!notation) { + return; + } + const desc = rollElem.dataset.desc || i18n("rollmaster.bbcode.default"); + + // TODO: add notation validator here, and show error if invalid + + const wrapper = document.createElement("div"); + wrapper.classList.add("bb-rollmaster-wrapper"); + + helper.renderGlimmer(wrapper, RollPreview, { + notation, + desc, + }); + + rollElem.replaceWith(wrapper); + }); + }); +} + +export default { + name: "rollmaster-composer-preview", + initialize() { + withPluginApi(initializeRollmasterPreview); + }, +}; diff --git a/assets/javascripts/discourse/initializers/preview.js b/assets/javascripts/discourse/initializers/preview.js deleted file mode 100644 index e4e4eaf..0000000 --- a/assets/javascripts/discourse/initializers/preview.js +++ /dev/null @@ -1,18 +0,0 @@ -import { withPluginApi } from "discourse/lib/plugin-api"; -import ComposerValidRoll from "../components/composer-valid-roll"; - -function initializeRollmasterPreview(api) { - const siteSettings = api.container.lookup("service:site-settings"); - if (!siteSettings.rollmaster_enabled) { - return; - } - - api.renderInOutlet("after-d-editor", ComposerValidRoll); -} - -export default { - name: "rollmaster-composer-preview", - initialize() { - withPluginApi("2.0.0", initializeRollmasterPreview); - }, -}; diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 87558cf..369dc3c 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -18,6 +18,7 @@ en: empty: "No rolls" bbcode: placeholder: "Rolling: " + default: "Roll" validator: loading: "Validating roll notation..." success: "All roll notations are valid" From cd8ce7663fb25b4c0759158608dffbefb6b804fb Mon Sep 17 00:00:00 2001 From: Steven Chang Date: Fri, 21 Aug 2026 18:34:52 +0000 Subject: [PATCH 09/15] Simplify current rolls code --- .../javascripts/discourse/initializers/decorate-post.gjs | 7 ++++++- lib/rollmaster/roll_history.rb | 4 ---- plugin.rb | 4 +--- spec/integration/bbcode_spec.rb | 1 - 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/assets/javascripts/discourse/initializers/decorate-post.gjs b/assets/javascripts/discourse/initializers/decorate-post.gjs index 016df05..58f8ab4 100644 --- a/assets/javascripts/discourse/initializers/decorate-post.gjs +++ b/assets/javascripts/discourse/initializers/decorate-post.gjs @@ -28,11 +28,16 @@ function decorateCookedElement(el, helper) { return; } - const rolls = helper.getModel().rolls; + const model = helper.getModel(); + const rolls = model.rolls; const rollElems = el.querySelectorAll( ".bb-rollmaster[data-notation][data-roll-id]" ); + model.current_roll_ids = [...rollElems].map((e) => + Number(e.getAttribute("data-roll-id")) + ); + rollElems.forEach((rollElem) => { const rollId = rollElem.getAttribute("data-roll-id"); const roll = rolls.find((r) => r.id.toString() === rollId); diff --git a/lib/rollmaster/roll_history.rb b/lib/rollmaster/roll_history.rb index 06e1d2e..52b803c 100644 --- a/lib/rollmaster/roll_history.rb +++ b/lib/rollmaster/roll_history.rb @@ -4,10 +4,6 @@ module ::Rollmaster class RollHistory SELECTOR_QUERY = ".bb-rollmaster[data-roll-id]".freeze - def self.current_roll_ids(cooked) - roll_entries(cooked).map { |entry| entry[:id] } - end - def self.roll_changes(previous_cooked, current_cooked) previous_rolls = roll_entries(previous_cooked) current_rolls = roll_entries(current_cooked) diff --git a/plugin.rb b/plugin.rb index 9bfb2db..0fa141c 100644 --- a/plugin.rb +++ b/plugin.rb @@ -38,11 +38,9 @@ module ::Rollmaster add_to_class(:post, :rolls) do ::Rollmaster::Roll.where(post_id: id).order(created_at: :desc, id: :desc) if has_rolls? end - add_to_class(:post, :current_roll_ids) { ::Rollmaster::RollHistory.current_roll_ids(cooked) } add_to_serializer(:post, :has_rolls?) { object.has_rolls? } - add_to_serializer(:post, :current_roll_ids) { object.current_roll_ids } - add_to_serializer(:post, :rolls) do + add_to_serializer(:post, :rolls, include_condition: -> { object.has_rolls? }) do (object.rolls || []).map { |roll| ::Rollmaster::RollSerializer.new(roll, root: false) } end diff --git a/spec/integration/bbcode_spec.rb b/spec/integration/bbcode_spec.rb index edaafda..9f5c655 100644 --- a/spec/integration/bbcode_spec.rb +++ b/spec/integration/bbcode_spec.rb @@ -145,7 +145,6 @@ rolls = ::Rollmaster::Roll.where(post_id: post.id).order(:created_at, :id) expect(rolls.map(&:raw)).to eq(%w[1d6 1d8]) - expect(post.reload.current_roll_ids).to eq([initial_roll.id]) expect(restored_cpp.html).to include("data-roll-id=\"#{initial_roll.id}\"") end From 37e37ec01f195dd9169664f07f5d0fb5c89decb4 Mon Sep 17 00:00:00 2001 From: Steven Chang Date: Fri, 21 Aug 2026 20:51:32 +0000 Subject: [PATCH 10/15] Simplify roll rendering --- .../components/composer-valid-roll.gjs | 132 ---------- .../components/rolls-post-menu-button.gjs | 8 +- .../discourse/initializers/decorate-post.gjs | 92 +++---- .../discourse/initializers/preview.gjs | 68 ----- .../lib/discourse-markdown/bbcode.js | 76 ++++-- assets/stylesheets/common/index.scss | 242 ++++++++---------- config/locales/client.en.yml | 5 - lib/rollmaster/handle_cooked_post_process.rb | 22 +- lib/rollmaster/roll_history.rb | 2 +- spec/integration/bbcode_spec.rb | 2 +- test/javascripts/acceptance/composer-test.js | 64 +++-- 11 files changed, 266 insertions(+), 447 deletions(-) delete mode 100644 assets/javascripts/discourse/components/composer-valid-roll.gjs delete mode 100644 assets/javascripts/discourse/initializers/preview.gjs diff --git a/assets/javascripts/discourse/components/composer-valid-roll.gjs b/assets/javascripts/discourse/components/composer-valid-roll.gjs deleted file mode 100644 index 7b3837e..0000000 --- a/assets/javascripts/discourse/components/composer-valid-roll.gjs +++ /dev/null @@ -1,132 +0,0 @@ -import Component from "@glimmer/component"; -import { tracked } from "@glimmer/tracking"; -import { action } from "@ember/object"; -import didInsert from "@ember/render-modifiers/modifiers/did-insert"; -import didUpdate from "@ember/render-modifiers/modifiers/did-update"; -import { debounce } from "@ember/runloop"; -import loadscript from "discourse/lib/load-script"; -import { cook } from "discourse/lib/text"; -import dIcon from "discourse/ui-kit/helpers/d-icon"; -import { i18n } from "discourse-i18n"; -/* global rpgDiceRoller */ - -const ROLL_SELECTOR = ".bb-rollmaster[data-notation]"; -const NOTE_ATTR = "data-notation"; - -export default class ComposerValidRoll extends Component { - @tracked hasRolls = false; - @tracked loading = false; - @tracked errors = []; - - get title() { - if (this.loading) { - return i18n("rollmaster.validator.loading"); - } - if (!this.hasRolls) { - return ""; - } - if (this.errors.length) { - return i18n("rollmaster.validator.error"); - } else { - return i18n("rollmaster.validator.success"); - } - } - - /** - * @returns {string} - */ - get raw() { - return this.args.composer?.reply; - } - - get mayHaveRolls() { - if (!this.raw) { - return false; - } - const str = this.raw.toLowerCase(); - return str.includes("[roll]") && str.includes("[/roll]"); - } - - @action - async checkRolls(raw) { - this.loading = true; - const actualPreview = this.args.composer.getCookedHtml(); - if (actualPreview) { - this.validateRollsFromPost( - document.querySelector("#reply-control.show-preview .d-editor-preview") - ); - return; - } - - const cooked = await cook(raw); - const template = document.createElement("template"); - template.innerHTML = cooked; - this.validateRollsFromPost(template.content); - } - - @action - asyncCheckRolls() { - debounce(this, this.checkRolls, this.raw, 1000); - } - - /** - * @param {Element} post - */ - async validateRollsFromPost(post) { - await this.loadRpgDiceRoller(); - /** @type NodeList */ - const rollEls = post.querySelectorAll(ROLL_SELECTOR); - this.errors = []; - this.hasRolls = !!rollEls.length; - this.loading = false; - - if (!this.hasRolls) { - return; - } - - /** @type string[] */ - rollEls.forEach((el) => { - /** @type string */ - const notation = el.getAttribute(NOTE_ATTR); - try { - // TODO: Handle descriptions separately. parser won't be able to handle 2d20+4 // test - // see https://github.com/dice-roller/rpg-dice-roller/issues/287 - rpgDiceRoller.Parser.parse(notation); - } catch (err) { - this.errors.push(err); - // eslint-disable-next-line no-console - console.warn("Rollmaster: Error parsing notation", notation, err); - } - }); - } - - async loadRpgDiceRoller() { - await Promise.all([ - loadscript("/plugins/rollmaster/vendors/math.js"), - loadscript("/plugins/rollmaster/vendors/random-js.min.js"), - ]); - await loadscript("/plugins/rollmaster/vendors/rpg-dice-roller.min.js"); - } - - -} diff --git a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs index 1e3472a..8d07a31 100644 --- a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs +++ b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs @@ -4,6 +4,7 @@ import { fn } from "@ember/helper"; import { action } from "@ember/object"; import DButton from "discourse/components/d-button"; import DModal from "discourse/components/d-modal"; +import dConcatClass from "discourse/ui-kit/helpers/d-concat-class"; import { i18n } from "discourse-i18n"; export default class RollsPostMenuButton extends Component { @@ -71,10 +72,9 @@ export default class RollsPostMenuButton extends Component { >
diff --git a/assets/javascripts/discourse/initializers/decorate-post.gjs b/assets/javascripts/discourse/initializers/decorate-post.gjs index 58f8ab4..c0e20be 100644 --- a/assets/javascripts/discourse/initializers/decorate-post.gjs +++ b/assets/javascripts/discourse/initializers/decorate-post.gjs @@ -1,60 +1,60 @@ +import { iconElement } from "discourse/lib/icon-library"; +import loadscript from "discourse/lib/load-script"; import { withPluginApi } from "discourse/lib/plugin-api"; -import dIcon from "discourse/ui-kit/helpers/d-icon"; -import { i18n } from "discourse-i18n"; import RollsPostMenuButton from "../components/rolls-post-menu-button"; -const RollResult = ; +/* global rpgDiceRoller */ + +const SAVED_SELECTOR = "blockquote.bb-rollmaster-result[data-roll-id]"; +const PENDING_SELECTOR = "blockquote.bb-rollmaster-result:not([data-roll-id])"; + +async function loadRpgDiceRoller() { + await Promise.all([ + loadscript("/plugins/rollmaster/vendors/math.js"), + loadscript("/plugins/rollmaster/vendors/random-js.min.js"), + ]); + await loadscript("/plugins/rollmaster/vendors/rpg-dice-roller.min.js"); +} function decorateCookedElement(el, helper) { - if (!helper?.getModel()?.has_rolls) { - return; - } + const model = helper?.getModel(); - const model = helper.getModel(); - const rolls = model.rolls; - const rollElems = el.querySelectorAll( - ".bb-rollmaster[data-notation][data-roll-id]" - ); + if (model?.has_rolls) { + const savedElems = el.querySelectorAll(SAVED_SELECTOR); + model.current_roll_ids = [...savedElems].map((e) => + Number(e.getAttribute("data-roll-id")) + ); + } - model.current_roll_ids = [...rollElems].map((e) => - Number(e.getAttribute("data-roll-id")) - ); + const pendingElems = el.querySelectorAll(PENDING_SELECTOR); + if (!pendingElems.length) { + return; + } - rollElems.forEach((rollElem) => { - const rollId = rollElem.getAttribute("data-roll-id"); - const roll = rolls.find((r) => r.id.toString() === rollId); - if (!roll) { - return; + pendingElems.forEach((blockquote) => { + const descEl = blockquote.querySelector(".bb-rollmaster-description"); + if (descEl && !descEl.querySelector(".d-icon")) { + descEl.prepend(iconElement("rollmaster-dices")); } + }); - roll.desc ??= i18n("rollmaster.bbcode.default"); + loadRpgDiceRoller().then(() => { + pendingElems.forEach((blockquote) => { + const notation = blockquote.getAttribute("data-notation"); + const resultsEl = blockquote.querySelector(".bb-rollmaster-results"); + if (!notation || !resultsEl) { + return; + } - // full replacement of the roll element with a glimmer component - const wrapper = document.createElement("div"); - wrapper.classList.add("bb-rollmaster-wrapper"); - helper.renderGlimmer( - wrapper, - - ); - rollElem.replaceWith(wrapper); + try { + rpgDiceRoller.Parser.parse(notation); + resultsEl.textContent = "???"; + blockquote.classList.remove("--error"); + } catch (err) { + resultsEl.textContent = err.message; + blockquote.classList.add("--error"); + } + }); }); } diff --git a/assets/javascripts/discourse/initializers/preview.gjs b/assets/javascripts/discourse/initializers/preview.gjs deleted file mode 100644 index 6260594..0000000 --- a/assets/javascripts/discourse/initializers/preview.gjs +++ /dev/null @@ -1,68 +0,0 @@ -import { withPluginApi } from "discourse/lib/plugin-api"; -import dIcon from "discourse/ui-kit/helpers/d-icon"; -import { i18n } from "discourse-i18n"; -import ComposerValidRoll from "../components/composer-valid-roll"; - -const RollPreview = ; - -function initializeRollmasterPreview(api) { - const siteSettings = api.container.lookup("service:site-settings"); - if (!siteSettings.rollmaster_enabled) { - return; - } - - api.renderInOutlet("after-d-editor", ComposerValidRoll); - - api.decorateCookedElement((element, helper) => { - if (helper.getModel()) { - return; - } - // This is a preview, no model - - const rollElems = element.querySelectorAll( - ".bb-rollmaster[data-notation]:not([data-roll-id])" - ); - - rollElems.forEach((rollElem) => { - const notation = rollElem.dataset.notation; - if (!notation) { - return; - } - const desc = rollElem.dataset.desc || i18n("rollmaster.bbcode.default"); - - // TODO: add notation validator here, and show error if invalid - - const wrapper = document.createElement("div"); - wrapper.classList.add("bb-rollmaster-wrapper"); - - helper.renderGlimmer(wrapper, RollPreview, { - notation, - desc, - }); - - rollElem.replaceWith(wrapper); - }); - }); -} - -export default { - name: "rollmaster-composer-preview", - initialize() { - withPluginApi(initializeRollmasterPreview); - }, -}; diff --git a/assets/javascripts/lib/discourse-markdown/bbcode.js b/assets/javascripts/lib/discourse-markdown/bbcode.js index 52f2a6b..4f89a76 100644 --- a/assets/javascripts/lib/discourse-markdown/bbcode.js +++ b/assets/javascripts/lib/discourse-markdown/bbcode.js @@ -1,49 +1,79 @@ -import { i18n } from "discourse-i18n"; +const BLOCK_CLASS = "bb-rollmaster-result"; +const RESULTS_PLACEHOLDER = "???"; -const ROLL_CLASS = "bb-rollmaster"; +function buildRollTokens(state, tagInfo, content) { + const notation = content?.trim(); + const desc = tagInfo.attrs._default || null; -function applyRollAttrs(state, token, attrs, content) { + if (!notation) { + return false; + } + + let token; + + token = state.push("rollmaster_open", "blockquote", 1); token.attrs = [ - ["class", ROLL_CLASS], - ["data-notation", content], + ["class", BLOCK_CLASS], + ["data-notation", notation], ]; - - if (attrs._default) { - token.attrs.push(["data-desc", attrs._default]); + if (desc) { + token.attrs.push(["data-desc", desc]); } - if (content) { + token = state.push("rollmaster_title_open", "p", 1); + token.attrs = [["class", "bb-rollmaster-title"]]; + + token = state.push("rollmaster_desc_open", "span", 1); + token.attrs = [["class", "bb-rollmaster-description"]]; + if (desc) { token = state.push("text", "", 0); - token.content = i18n("rollmaster.bbcode.placeholder") + content; + token.content = `${desc}:`; } + state.push("rollmaster_desc_close", "span", -1); + + token = state.push("rollmaster_notation_open", "span", 1); + token.attrs = [["class", "bb-rollmaster-notation"]]; + token = state.push("text", "", 0); + token.content = notation; + state.push("rollmaster_notation_close", "span", -1); + + state.push("rollmaster_title_close", "p", -1); + + token = state.push("rollmaster_results_open", "p", 1); + token.attrs = [["class", "bb-rollmaster-results"]]; + token = state.push("text", "", 0); + token.content = RESULTS_PLACEHOLDER; + state.push("rollmaster_results_close", "p", -1); + + state.push("rollmaster_close", "blockquote", -1); + + return true; } const blockRule = { tag: "roll", replace(state, tagInfo, content) { - let token = state.push("roll_open", "div", 1); - - applyRollAttrs(state, token, tagInfo.attrs, content); - - state.push("roll_close", "div", -1); - return true; + return buildRollTokens(state, tagInfo, content); }, }; const inlineRule = { tag: "roll", replace(state, tagInfo, content) { - let token = state.push("roll_open", "span", 1); - - applyRollAttrs(state, token, tagInfo.attrs, content); - - state.push("roll_close", "span", -1); - return true; + return buildRollTokens(state, tagInfo, content); }, }; export function setup(helper) { - helper.allowList(["div.bb-rollmaster", "span.bb-rollmaster"]); + helper.allowList([ + "blockquote.bb-rollmaster-result", + "blockquote[data-notation]", + "blockquote[data-desc]", + "p.bb-rollmaster-title", + "p.bb-rollmaster-results", + "span.bb-rollmaster-description", + "span.bb-rollmaster-notation", + ]); helper.registerOptions((opts, siteSettings) => { opts.features["rollmaster"] = !!siteSettings.rollmaster_enabled; diff --git a/assets/stylesheets/common/index.scss b/assets/stylesheets/common/index.scss index 06035e1..13ef54d 100644 --- a/assets/stylesheets/common/index.scss +++ b/assets/stylesheets/common/index.scss @@ -1,37 +1,3 @@ -.rollmaster-valid-composer { - display: block; - position: absolute; - right: 0.125em; - bottom: 0em; - padding: 0.125em; - - svg.svg-roll { - --success-mild: color-mix( - in srgb, - var(--success-medium), - rgb(140, 140, 140) - ); - color: var(--success-mild, --success-medium); - - &:has(~ .rollmaster-spinner) { - color: var(--primary-low-mid); - } - - &:has(+ .roll__invalid) { - color: var(--danger); - } - } - - svg.roll__invalid { - color: var(--danger); - } -} - -.rollmaster-spinner { - animation: rotate-forever 1s infinite linear; - color: var(--primary-low-mid); -} - .bb-rollmaster-result { .bb-rollmaster-title { color: var(--primary-high-or-secondary-low); @@ -42,143 +8,149 @@ display: inline-block; font-size: var(--font-0-rem); margin: auto 0; - margin-right: 0.25em; + margin-inline-end: 0.25em; } } - .rollmaster-roll-history-modal { - .d-modal__body { - max-height: min(70vh, 40rem); - overflow-y: auto; - } + .bb-rollmaster-results { + margin-top: 0.25em; + font-family: var(--d-font-family--monospace); } - .rollmaster-roll-history { - display: flex; - flex-direction: column; - gap: 1rem; + &.--error { + .bb-rollmaster-results { + color: var(--danger); + } } +} - .rollmaster-roll-history__entry { - border: 1px solid var(--primary-low); - border-radius: 0.5rem; - padding: 0.875rem; - background: var(--secondary); +.rollmaster-roll-history-modal { + .d-modal__body { + max-height: min(70vh, 40rem); + overflow-y: auto; } +} - .rollmaster-roll-history__entry-header { - display: flex; - justify-content: space-between; - gap: 0.75rem; - align-items: center; - margin-bottom: 0.5rem; - } +.rollmaster-roll-history { + display: flex; + flex-direction: column; + gap: 1rem; +} - .rollmaster-roll-history__status { - display: inline-flex; - align-items: center; - border-radius: 999px; - padding: 0.125rem 0.5rem; - font-size: var(--font-down-1); - font-weight: var(--font-weight-semibold); - } +.rollmaster-roll-history__entry { + border: 1px solid var(--primary-low); + border-radius: 0.5rem; + padding: 0.875rem; + background: var(--secondary); +} + +.rollmaster-roll-history__entry-header { + display: flex; + justify-content: space-between; + gap: 0.75rem; + align-items: center; + margin-bottom: 0.5rem; +} + +.rollmaster-roll-history__status { + display: inline-flex; + align-items: center; + border-radius: 999px; + padding: 0.125rem 0.5rem; + font-size: var(--font-down-1); + font-weight: var(--font-weight-semibold); - .rollmaster-roll-history__status--current { + &.--current { background: var(--success-low); color: var(--success); } - .rollmaster-roll-history__status--historical { + &.--historical { background: var(--primary-low); color: var(--primary-high); } +} - .rollmaster-roll-history__timestamp { - color: var(--primary-medium); - font-size: var(--font-down-1); - } - - .rollmaster-roll-history__description { - margin: 0 0 0.75rem; - color: var(--primary-high); - } +.rollmaster-roll-history__timestamp { + color: var(--primary-medium); + font-size: var(--font-down-1); +} - .rollmaster-roll-history__details { - display: grid; - gap: 0.75rem; - margin: 0; - } +.rollmaster-roll-history__description { + margin: 0 0 0.75rem; + color: var(--primary-high); +} - .rollmaster-roll-history__detail { - display: grid; - gap: 0.125rem; +.rollmaster-roll-history__details { + display: grid; + gap: 0.75rem; + margin: 0; +} - dt { - color: var(--primary-medium); - font-size: var(--font-down-1); - } +.rollmaster-roll-history__detail { + display: grid; + gap: 0.125rem; - dd { - margin: 0; - font-family: var(--d-font-family--monospace); - } + dt { + color: var(--primary-medium); + font-size: var(--font-down-1); } - .rollmaster-roll-history__empty { + dd { margin: 0; - color: var(--primary-medium); + font-family: var(--d-font-family--monospace); } +} - .rollmaster-revision-rolls { - display: grid; - grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); - gap: 0.75rem; - align-items: start; +.rollmaster-roll-history__empty { + margin: 0; + color: var(--primary-medium); +} - .revision-content { - min-width: 0; - } - } +.rollmaster-revision-rolls { + display: grid; + grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); + gap: 0.75rem; + align-items: start; - .rollmaster-revision-rolls__heading { - margin: 0 0 0.5rem; - color: var(--primary-medium); - font-size: var(--font-down-1); - font-weight: var(--font-weight-semibold); + .revision-content { + min-width: 0; } +} - .rollmaster-revision-rolls__list { - margin: 0; - padding-left: 1rem; - } +.rollmaster-revision-rolls__heading { + margin: 0 0 0.5rem; + color: var(--primary-medium); + font-size: var(--font-down-1); + font-weight: var(--font-weight-semibold); +} - .rollmaster-revision-rolls__entry { - margin-bottom: 0.25rem; - font-family: var(--d-font-family--monospace); - } +.rollmaster-revision-rolls__list { + margin: 0; + padding-inline-start: 1rem; +} - .rollmaster-revision-rolls__description { - font-family: var(--d-font-family); - font-weight: var(--font-weight-semibold); - } +.rollmaster-revision-rolls__entry { + margin-bottom: 0.25rem; + font-family: var(--d-font-family--monospace); +} - .rollmaster-revision-rolls__notation, - .rollmaster-revision-rolls__result { - display: inline; - } +.rollmaster-revision-rolls__description { + font-family: var(--d-font-family); + font-weight: var(--font-weight-semibold); +} - .rollmaster-revision-rolls__result::before { - content: ": "; - } +.rollmaster-revision-rolls__notation, +.rollmaster-revision-rolls__result { + display: inline; +} - .rollmaster-revision-rolls__empty, - .rollmaster-revision-rolls__arrow { - margin: 0; - color: var(--primary-medium); - } +.rollmaster-revision-rolls__result::before { + content: ": "; +} - .bb-rollmaster-results { - margin-top: 0.25em; - font-family: var(--d-font-family--monospace); - } +.rollmaster-revision-rolls__empty, +.rollmaster-revision-rolls__arrow { + margin: 0; + color: var(--primary-medium); } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 369dc3c..1ca2cc4 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -17,9 +17,4 @@ en: title: "Rolls" empty: "No rolls" bbcode: - placeholder: "Rolling: " default: "Roll" - validator: - loading: "Validating roll notation..." - success: "All roll notations are valid" - error: "Invalid roll notation found" diff --git a/lib/rollmaster/handle_cooked_post_process.rb b/lib/rollmaster/handle_cooked_post_process.rb index 52344a0..176f23c 100644 --- a/lib/rollmaster/handle_cooked_post_process.rb +++ b/lib/rollmaster/handle_cooked_post_process.rb @@ -1,20 +1,17 @@ # frozen_string_literal: true module ::Rollmaster - SELECTOR_QUERY = ".bb-rollmaster[data-notation]" + SELECTOR_QUERY = "blockquote.bb-rollmaster-result[data-notation]:not([data-roll-id])" class HandleCookedPostProcess def self.process(doc, post) - # Add your processing logic here - roll_elements = doc .css(SELECTOR_QUERY) .filter_map do |roll_element| - notation = roll_element.attribute("data-notation").value + notation = roll_element.attribute("data-notation")&.value next if notation.blank? - roll_element.content = "" { raw: notation, dom: roll_element, desc: roll_element.attribute("data-desc")&.value } end @@ -26,8 +23,19 @@ def self.process(doc, post) save_rolls(roll_elements, post) roll_elements.each do |roll| - roll[:dom].content = roll[:error] ? roll[:raw] : "#{roll[:raw]}: #{roll[:result]}" - roll[:dom]["data-roll-id"] = roll[:id] if roll[:id] + result_el = roll[:dom].at_css(".bb-rollmaster-results") + desc_el = roll[:dom].at_css(".bb-rollmaster-description") + + svg = SvgSprite.raw_svg("rollmaster-dices") + desc_el.prepend_child(Nokogiri::HTML5.fragment(svg)) if desc_el && svg.present? + + if roll[:error] + roll[:dom]["class"] = "#{roll[:dom]["class"]} --error" + result_el&.content = roll[:result] + else + roll[:dom]["data-roll-id"] = roll[:id].to_s if roll[:id] + result_el&.content = roll[:result] + end end true diff --git a/lib/rollmaster/roll_history.rb b/lib/rollmaster/roll_history.rb index 52b803c..13e3872 100644 --- a/lib/rollmaster/roll_history.rb +++ b/lib/rollmaster/roll_history.rb @@ -2,7 +2,7 @@ module ::Rollmaster class RollHistory - SELECTOR_QUERY = ".bb-rollmaster[data-roll-id]".freeze + SELECTOR_QUERY = "blockquote.bb-rollmaster-result[data-roll-id]".freeze def self.roll_changes(previous_cooked, current_cooked) previous_rolls = roll_entries(previous_cooked) diff --git a/spec/integration/bbcode_spec.rb b/spec/integration/bbcode_spec.rb index 9f5c655..6a8caec 100644 --- a/spec/integration/bbcode_spec.rb +++ b/spec/integration/bbcode_spec.rb @@ -63,7 +63,7 @@ roll_ids = Nokogiri::HTML5 .fragment(cpp.html) - .css(".bb-rollmaster") + .css("blockquote.bb-rollmaster-result") .map { |element| element["data-roll-id"].to_i } expect(roll_ids).to eq(original_roll_ids) diff --git a/test/javascripts/acceptance/composer-test.js b/test/javascripts/acceptance/composer-test.js index 7cb4ff2..79afc32 100644 --- a/test/javascripts/acceptance/composer-test.js +++ b/test/javascripts/acceptance/composer-test.js @@ -1,7 +1,6 @@ -import { click, fillIn, visit } from "@ember/test-helpers"; +import { click,fillIn, visit, waitUntil } from "@ember/test-helpers"; import { test } from "qunit"; import { acceptance } from "discourse/tests/helpers/qunit-helpers"; -import { i18n } from "discourse-i18n"; acceptance("Rollmaster - composer", function (needs) { needs.user(); @@ -12,48 +11,63 @@ acceptance("Rollmaster - composer", function (needs) { allow_uncategorized_topics: true, }); - test("bbcode [roll] is rendered", async function (assert) { + test("bbcode [roll] renders a blockquote in preview", async function (assert) { await visit("/"); await click("#create-topic"); await fillIn(".d-editor-input", "hello world"); - assert.dom(".d-editor-preview").hasText("hello world"); - await fillIn(".d-editor-input", "[roll]test[/roll]"); - - assert - .dom(".d-editor-preview .bb-rollmaster") - .hasAttribute("data-notation", "test"); - await fillIn(".d-editor-input", "[roll]2d20[/roll]"); assert - .dom(".d-editor-preview .bb-rollmaster") - .hasAttribute("data-notation", "2d20"); + .dom(".d-editor-preview blockquote.bb-rollmaster-result") + .hasAttribute("data-notation", "2d20", "blockquote has data-notation"); + assert + .dom(".d-editor-preview .bb-rollmaster-results") + .hasText("???", "results show placeholder before validation"); }); - test("[roll] notation is validated", async function (assert) { + test("[roll] valid notation does not show error state", async function (assert) { await visit("/"); await click("#create-topic"); - await fillIn(".d-editor-input", "hello world"); - - assert.dom(".d-editor-preview").hasText("hello world"); - assert.dom(".rollmaster-valid-composer").doesNotExist(); - await fillIn(".d-editor-input", "[roll]2d20[/roll]"); - assert.dom(".rollmaster-valid-composer").exists(); + await waitUntil( + () => + !document + .querySelector( + ".d-editor-preview blockquote.bb-rollmaster-result:not(.--error) .bb-rollmaster-results" + ) + ?.textContent.includes("???") || + document.querySelector( + ".d-editor-preview blockquote.bb-rollmaster-result" + ), + { timeout: 5000 } + ); + assert - .dom(".rollmaster-valid-composer") - .hasAttribute("title", i18n("rollmaster.validator.success")); + .dom(".d-editor-preview blockquote.bb-rollmaster-result") + .doesNotHaveClass("--error", "valid notation has no error state"); + }); + + test("[roll] invalid notation shows error state", async function (assert) { + await visit("/"); + await click("#create-topic"); await fillIn(".d-editor-input", "[roll]junk[/roll]"); - assert.dom(".rollmaster-valid-composer").exists(); + + await waitUntil( + () => + document.querySelector( + ".d-editor-preview blockquote.bb-rollmaster-result.--error" + ), + { timeout: 5000 } + ); + assert - .dom(".rollmaster-valid-composer") - .hasAttribute("title", i18n("rollmaster.validator.error")); - assert.dom(".rollmaster-valid-composer .roll__invalid").exists(); + .dom(".d-editor-preview blockquote.bb-rollmaster-result") + .hasClass("--error", "invalid notation shows error state"); }); }); From e770a71f5cf20318d7095366b4f680b39a31525a Mon Sep 17 00:00:00 2001 From: Steven Chang Date: Fri, 21 Aug 2026 21:28:08 +0000 Subject: [PATCH 11/15] Roll History simplify and clean up --- .../components/roll-history-entry.gjs | 89 +++++++++++++ .../components/rolls-post-menu-button.gjs | 58 +-------- .../rollmaster-roll-changes.gjs | 88 ------------- .../rollmaster-transformer.js | 11 -- assets/stylesheets/common/index.scss | 120 +++--------------- config/locales/client.en.yml | 8 +- lib/rollmaster/roll_history.rb | 53 -------- plugin.rb | 7 - spec/requests/posts_controller_spec.rb | 52 -------- .../page_objects/modals/roll_history.rb | 7 +- .../modals/rollmaster_post_history.rb | 29 ----- spec/system/post_history_rolls_spec.rb | 56 -------- 12 files changed, 114 insertions(+), 464 deletions(-) create mode 100644 assets/javascripts/discourse/components/roll-history-entry.gjs delete mode 100644 assets/javascripts/discourse/connectors/post-revisions/rollmaster-roll-changes.gjs delete mode 100644 assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js delete mode 100644 lib/rollmaster/roll_history.rb delete mode 100644 spec/requests/posts_controller_spec.rb delete mode 100644 spec/system/page_objects/modals/rollmaster_post_history.rb delete mode 100644 spec/system/post_history_rolls_spec.rb diff --git a/assets/javascripts/discourse/components/roll-history-entry.gjs b/assets/javascripts/discourse/components/roll-history-entry.gjs new file mode 100644 index 0000000..6739558 --- /dev/null +++ b/assets/javascripts/discourse/components/roll-history-entry.gjs @@ -0,0 +1,89 @@ +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { action } from "@ember/object"; +import { cancel } from "@ember/runloop"; +import DButton from "discourse/components/d-button"; +import discourseLater from "discourse/lib/later"; +import { clipboardCopy } from "discourse/lib/utilities"; +import dAgeWithTooltip from "discourse/ui-kit/helpers/d-age-with-tooltip"; +import dConcatClass from "discourse/ui-kit/helpers/d-concat-class"; +import dIcon from "discourse/ui-kit/helpers/d-icon"; +import { i18n } from "discourse-i18n"; + +export default class RollHistoryEntry extends Component { + @tracked copied = false; + #copyTimer = null; + + willDestroy() { + super.willDestroy(...arguments); + cancel(this.#copyTimer); + } + + buildBBCode() { + const { desc, raw } = this.args.roll; + return desc ? `[roll="${desc}"]${raw}[/roll]` : `[roll]${raw}[/roll]`; + } + + @action + async copyBBCode() { + await clipboardCopy(this.buildBBCode()); + cancel(this.#copyTimer); + this.copied = true; + this.#copyTimer = discourseLater(() => (this.copied = false), 2000); + } + + +} diff --git a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs index 8d07a31..6e1bb15 100644 --- a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs +++ b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs @@ -4,8 +4,8 @@ import { fn } from "@ember/helper"; import { action } from "@ember/object"; import DButton from "discourse/components/d-button"; import DModal from "discourse/components/d-modal"; -import dConcatClass from "discourse/ui-kit/helpers/d-concat-class"; import { i18n } from "discourse-i18n"; +import RollHistoryEntry from "./roll-history-entry"; export default class RollsPostMenuButton extends Component { static hidden() { @@ -27,22 +27,10 @@ export default class RollsPostMenuButton extends Component { ) .map((roll) => ({ ...roll, - formattedCreatedAt: this.formatTimestamp(roll.created_at), isCurrent: this.currentRollIds.has(Number(roll.id)), })); } - formatTimestamp(timestamp) { - if (!timestamp) { - return ""; - } - - return new Intl.DateTimeFormat(undefined, { - dateStyle: "medium", - timeStyle: "short", - }).format(new Date(timestamp)); - } - @action showRolls() { this.modalIsOpen = true; @@ -66,49 +54,7 @@ export default class RollsPostMenuButton extends Component { >
{{#each this.rolls as |roll|}} -
-
- - {{if - roll.isCurrent - (i18n "rollmaster.post.current") - (i18n "rollmaster.post.historical") - }} - - -
- - {{#if roll.desc}} -

- {{roll.desc}} -

- {{/if}} - -
-
-
{{i18n "rollmaster.post.notation"}}
-
{{roll.notation}}
-
-
-
{{i18n "rollmaster.post.result"}}
-
{{roll.result}}
-
-
-
+ {{else}}

-

-
-

- {{i18n "rollmaster.revisions.title"}} -

- - {{#if this.previousRolls.length}} -
    - {{#each this.previousRolls as |roll|}} -
  • - {{#if roll.desc}} - - {{roll.desc}}: - - {{/if}} - - {{roll.notation}} - - - {{roll.result}} - -
  • - {{/each}} -
- {{else}} -

- {{i18n "rollmaster.revisions.empty"}} -

- {{/if}} -
- - {{#if (or this.previousRolls.length this.currentRolls.length)}} -
→
- {{/if}} - -
-

- {{i18n "rollmaster.revisions.title"}} -

- - {{#if this.currentRolls.length}} -
    - {{#each this.currentRolls as |roll|}} -
  • - {{#if roll.desc}} - - {{roll.desc}}: - - {{/if}} - - {{roll.notation}} - - - {{roll.result}} - -
  • - {{/each}} -
- {{else}} -

- {{i18n "rollmaster.revisions.empty"}} -

- {{/if}} -
-
- -} diff --git a/assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js b/assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js deleted file mode 100644 index 2073464..0000000 --- a/assets/javascripts/discourse/pre-initializers/rollmaster-transformer.js +++ /dev/null @@ -1,11 +0,0 @@ -import { withPluginApi } from "discourse/lib/plugin-api"; - -export default { - before: "freeze-valid-transformers", - - initialize() { - withPluginApi((api) => { - api.addValueTransformerName("rollmaster-cooked-roll-result"); - }); - }, -}; diff --git a/assets/stylesheets/common/index.scss b/assets/stylesheets/common/index.scss index 13ef54d..9f1def3 100644 --- a/assets/stylesheets/common/index.scss +++ b/assets/stylesheets/common/index.scss @@ -24,6 +24,8 @@ } } +// Modal + .rollmaster-roll-history-modal { .d-modal__body { max-height: min(70vh, 40rem); @@ -37,120 +39,32 @@ gap: 1rem; } -.rollmaster-roll-history__entry { - border: 1px solid var(--primary-low); - border-radius: 0.5rem; - padding: 0.875rem; - background: var(--secondary); -} - -.rollmaster-roll-history__entry-header { - display: flex; - justify-content: space-between; - gap: 0.75rem; - align-items: center; - margin-bottom: 0.5rem; -} - -.rollmaster-roll-history__status { - display: inline-flex; - align-items: center; - border-radius: 999px; - padding: 0.125rem 0.5rem; - font-size: var(--font-down-1); - font-weight: var(--font-weight-semibold); - - &.--current { - background: var(--success-low); - color: var(--success); - } - - &.--historical { - background: var(--primary-low); - color: var(--primary-high); - } -} - -.rollmaster-roll-history__timestamp { - color: var(--primary-medium); - font-size: var(--font-down-1); -} - -.rollmaster-roll-history__description { - margin: 0 0 0.75rem; - color: var(--primary-high); -} - -.rollmaster-roll-history__details { - display: grid; - gap: 0.75rem; - margin: 0; -} - -.rollmaster-roll-history__detail { - display: grid; - gap: 0.125rem; - - dt { - color: var(--primary-medium); - font-size: var(--font-down-1); - } - - dd { - margin: 0; - font-family: var(--d-font-family--monospace); - } -} - .rollmaster-roll-history__empty { margin: 0; color: var(--primary-medium); } -.rollmaster-revision-rolls { - display: grid; - grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); - gap: 0.75rem; - align-items: start; - - .revision-content { - min-width: 0; +.rollmaster-roll-history__roll { + &.--historical { + opacity: 0.65; } } -.rollmaster-revision-rolls__heading { - margin: 0 0 0.5rem; - color: var(--primary-medium); - font-size: var(--font-down-1); - font-weight: var(--font-weight-semibold); -} - -.rollmaster-revision-rolls__list { - margin: 0; - padding-inline-start: 1rem; -} - -.rollmaster-revision-rolls__entry { - margin-bottom: 0.25rem; - font-family: var(--d-font-family--monospace); -} - -.rollmaster-revision-rolls__description { - font-family: var(--d-font-family); - font-weight: var(--font-weight-semibold); -} - -.rollmaster-revision-rolls__notation, -.rollmaster-revision-rolls__result { - display: inline; +.rollmaster-roll-history__roll-controls { + display: flex; + align-items: center; + justify-content: flex-end; + gap: 0.5rem; + margin-bottom: 0.5rem; } -.rollmaster-revision-rolls__result::before { - content: ": "; +.rollmaster-roll-history__historical-indicator { + display: flex; + align-items: center; + color: var(--primary-medium); } -.rollmaster-revision-rolls__empty, -.rollmaster-revision-rolls__arrow { - margin: 0; +.rollmaster-roll-history__timestamp { color: var(--primary-medium); + font-size: var(--font-down-1); } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 1ca2cc4..dd335c6 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -10,11 +10,9 @@ en: title: "View roll history" current: "Current" historical: "Historical" - notation: "Notation" - result: "Result" + historical_tooltip: "Not in the current post" + copy: "Copy BBCode" + copied: "Copied!" empty: "No rolls have been saved for this post." - revisions: - title: "Rolls" - empty: "No rolls" bbcode: default: "Roll" diff --git a/lib/rollmaster/roll_history.rb b/lib/rollmaster/roll_history.rb deleted file mode 100644 index 13e3872..0000000 --- a/lib/rollmaster/roll_history.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -module ::Rollmaster - class RollHistory - SELECTOR_QUERY = "blockquote.bb-rollmaster-result[data-roll-id]".freeze - - def self.roll_changes(previous_cooked, current_cooked) - previous_rolls = roll_entries(previous_cooked) - current_rolls = roll_entries(current_cooked) - - return if previous_rolls.blank? && current_rolls.blank? - return if previous_rolls == current_rolls - - { previous: previous_rolls, current: current_rolls } - end - - def self.roll_entries(cooked) - roll_snapshots = parse_roll_snapshots(cooked) - return [] if roll_snapshots.empty? - - results_by_id = - ::Rollmaster::Roll - .where(id: roll_snapshots.map { |entry| entry[:id] }) - .pluck(:id, :result) - .to_h - - roll_snapshots.filter_map do |entry| - result = results_by_id[entry[:id]] - next if result.blank? - - entry.merge(result: result) - end - end - - def self.parse_roll_snapshots(cooked) - return [] if cooked.blank? - - Nokogiri::HTML5 - .fragment(cooked) - .css(SELECTOR_QUERY) - .filter_map do |element| - id = element["data-roll-id"].to_i - next if id.zero? - - { - id: id, - notation: element["data-notation"].to_s.strip, - desc: element["data-desc"].presence, - } - end - end - end -end diff --git a/plugin.rb b/plugin.rb index 0fa141c..58687d1 100644 --- a/plugin.rb +++ b/plugin.rb @@ -18,7 +18,6 @@ module ::Rollmaster end require_relative "lib/rollmaster/engine" -require_relative "lib/rollmaster/roll_history" after_initialize do # Code which should run after Rails has finished booting @@ -44,11 +43,5 @@ module ::Rollmaster (object.rolls || []).map { |roll| ::Rollmaster::RollSerializer.new(roll, root: false) } end - add_to_serializer( - :post_revision, - :roll_changes, - include_condition: -> { roll_changes.present? }, - ) { ::Rollmaster::RollHistory.roll_changes(previous["cooked"], current["cooked"]) } - # TODO: consider :chat_message_processed as well end diff --git a/spec/requests/posts_controller_spec.rb b/spec/requests/posts_controller_spec.rb deleted file mode 100644 index dc875dc..0000000 --- a/spec/requests/posts_controller_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe PostsController, type: :request do - fab!(:user) - fab!(:topic) { Fabricate(:topic, user: user) } - - let(:post) { Fabricate(:post, topic: topic, user: user, raw: "Opening roll: [roll]1d6[/roll]") } - - before do - enable_current_plugin - SiteSetting.rollmaster_enabled = true - SiteSetting.editing_grace_period = 0 - - process_initial_roll_state(post) - revise_post(post, "Changed roll: [roll]1d8[/roll]") - revise_post(post, "Back again: [roll]1d6[/roll]") - - sign_in(user) - end - - describe "#latest_revision" do - it "includes roll changes for the compared revisions" do - get "/posts/#{post.id}/revisions/latest.json" - - expect(response).to have_http_status(:ok) - expect( - response.parsed_body.dig("roll_changes", "previous").map { |entry| entry["notation"] }, - ).to eq(["1d8"]) - expect( - response.parsed_body.dig("roll_changes", "current").map { |entry| entry["notation"] }, - ).to eq(["1d6"]) - expect(response.parsed_body.dig("roll_changes", "current").first["id"]).not_to eq( - response.parsed_body.dig("roll_changes", "previous").first["id"], - ) - end - end - - def process_initial_roll_state(post) - cpp = CookedPostProcessor.new(post) - cpp.post_process - post.update_column(:cooked, cpp.html) - post.reload - end - - def revise_post(post, raw) - PostRevisor.new(post).revise!(user, { raw: raw, edit_reason: "reroll" }) - cpp = CookedPostProcessor.new(post) - cpp.post_process - post.update_column(:cooked, cpp.html) - post.reload - end -end diff --git a/spec/system/page_objects/modals/roll_history.rb b/spec/system/page_objects/modals/roll_history.rb index a3e1b6a..c0a90ec 100644 --- a/spec/system/page_objects/modals/roll_history.rb +++ b/spec/system/page_objects/modals/roll_history.rb @@ -14,10 +14,9 @@ def has_entry?(notation:, status:) end def entry_count(notation:, status:) - rows.count do |row| - row_text = row.text - row_text.include?(notation) && row_text.include?(status) - end + body + .all("[data-test-roll-history-row][data-test-roll-history-status='#{status.downcase}']") + .count { |row| row.text.include?(notation) } end private diff --git a/spec/system/page_objects/modals/rollmaster_post_history.rb b/spec/system/page_objects/modals/rollmaster_post_history.rb deleted file mode 100644 index 71faab5..0000000 --- a/spec/system/page_objects/modals/rollmaster_post_history.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module PageObjects - module Modals - class RollmasterPostHistory < PageObjects::Modals::PostHistory - def previous_roll_entries - roll_entries("[data-test-roll-revision-previous]") - end - - def current_roll_entries - roll_entries("[data-test-roll-revision-current]") - end - - def has_previous_roll_entry?(notation) - previous_roll_entries.any? { |entry| entry.include?(notation) } - end - - def has_current_roll_entry?(notation) - current_roll_entries.any? { |entry| entry.include?(notation) } - end - - private - - def roll_entries(scope) - body.all("#{scope} .rollmaster-revision-rolls__entry").map(&:text) - end - end - end -end diff --git a/spec/system/post_history_rolls_spec.rb b/spec/system/post_history_rolls_spec.rb deleted file mode 100644 index 461115d..0000000 --- a/spec/system/post_history_rolls_spec.rb +++ /dev/null @@ -1,56 +0,0 @@ -# frozen_string_literal: true - -RSpec.describe "Post history rolls", type: :system do - fab!(:user) { Fabricate(:user, refresh_auto_groups: true) } - fab!(:topic) { Fabricate(:topic, user: user) } - - let(:post) { Fabricate(:post, topic: topic, user: user, raw: "Opening roll: [roll]1d6[/roll]") } - let(:post_history_modal) { PageObjects::Modals::RollmasterPostHistory.new } - let(:topic_page) { PageObjects::Pages::Topic.new } - - before do - enable_current_plugin - SiteSetting.rollmaster_enabled = true - SiteSetting.editing_grace_period = 0 - - process_initial_roll_state(post) - revise_post(post, "Changed roll: [roll]1d8[/roll]") - revise_post(post, "Back again: [roll]1d6[/roll]") - - sign_in(user) - end - - it "shows roll changes while the user browses post history" do - topic_page.visit_topic(topic) - page.refresh - - topic_page.open_post_history(post) - - expect(post_history_modal.current_roll_entries.size).to eq(1) - expect(post_history_modal.previous_roll_entries.size).to eq(1) - expect(post_history_modal).to have_current_roll_entry("1d6") - expect(post_history_modal).to have_previous_roll_entry("1d8") - - post_history_modal.click_previous_revision - - expect(post_history_modal.current_roll_entries.size).to eq(1) - expect(post_history_modal.previous_roll_entries.size).to eq(1) - expect(post_history_modal).to have_current_roll_entry("1d8") - expect(post_history_modal).to have_previous_roll_entry("1d6") - end - - def process_initial_roll_state(post) - cpp = CookedPostProcessor.new(post) - cpp.post_process - post.update_column(:cooked, cpp.html) - post.reload - end - - def revise_post(post, raw) - PostRevisor.new(post).revise!(user, { raw: raw, edit_reason: "reroll" }) - cpp = CookedPostProcessor.new(post) - cpp.post_process - post.update_column(:cooked, cpp.html) - post.reload - end -end From 7b23d7dd590f094ff116c633cc025148542d3022 Mon Sep 17 00:00:00 2001 From: Steven Chang Date: Fri, 21 Aug 2026 21:39:08 +0000 Subject: [PATCH 12/15] test roll history entry --- .../components/roll-history-entry-test.gjs | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 test/javascripts/integration/components/roll-history-entry-test.gjs diff --git a/test/javascripts/integration/components/roll-history-entry-test.gjs b/test/javascripts/integration/components/roll-history-entry-test.gjs new file mode 100644 index 0000000..e593cd4 --- /dev/null +++ b/test/javascripts/integration/components/roll-history-entry-test.gjs @@ -0,0 +1,114 @@ +import { click, render } from "@ember/test-helpers"; +import { module, test } from "qunit"; +import sinon from "sinon"; +import { setupRenderingTest } from "discourse/tests/helpers/component-test"; +import RollHistoryEntry from "discourse/plugins/rollmaster/discourse/components/roll-history-entry"; + +function baseRoll(overrides = {}) { + return { + id: 1, + raw: "2d6", + notation: "2d6", + result: "4", + desc: null, + created_at: "2024-01-01T00:00:00Z", + isCurrent: true, + ...overrides, + }; +} + +module("Integration | Component | RollHistoryEntry", function (hooks) { + setupRenderingTest(hooks); + + test("renders notation and result", async function (assert) { + const roll = baseRoll(); + + await render(); + + assert.dom(".bb-rollmaster-notation").hasText("2d6", "notation is shown"); + assert.dom(".bb-rollmaster-results").hasText("4", "result is shown"); + }); + + test("uses default label when no description", async function (assert) { + const roll = baseRoll(); + + await render(); + + assert + .dom(".bb-rollmaster-description") + .includesText("Roll:", "default label shown when no desc"); + }); + + test("shows description when provided", async function (assert) { + const roll = baseRoll({ desc: "Strength check" }); + + await render(); + + assert + .dom(".bb-rollmaster-description") + .includesText("Strength check:", "provided description is shown"); + }); + + test("current roll has no historical marker or modifier", async function (assert) { + const roll = baseRoll({ isCurrent: true }); + + await render(); + + assert + .dom("blockquote") + .doesNotHaveClass( + "--historical", + "no --historical class on current roll" + ); + assert + .dom(".rollmaster-roll-history__historical-indicator") + .doesNotExist("no historical indicator on current roll"); + }); + + test("historical roll has --historical class and indicator", async function (assert) { + const roll = baseRoll({ isCurrent: false }); + + await render(); + + assert + .dom("blockquote") + .hasClass("--historical", "blockquote has --historical class"); + assert + .dom(".rollmaster-roll-history__historical-indicator") + .exists("historical indicator is shown"); + }); + + test("copies plain BBCode when no description", async function (assert) { + const writeText = sinon.stub().resolves(); + sinon.stub(window.navigator, "clipboard").get(() => ({ writeText })); + + const roll = baseRoll({ raw: "1d20", notation: "1d20" }); + + await render(); + await click("[data-test-copy-bbcode]"); + + assert.true( + writeText.calledWithExactly("[roll]1d20[/roll]"), + "plain BBCode copied without description" + ); + }); + + test("copies BBCode with description when desc is set", async function (assert) { + const writeText = sinon.stub().resolves(); + sinon.stub(window.navigator, "clipboard").get(() => ({ writeText })); + + const roll = baseRoll({ + raw: "1d20", + notation: "1d20", + desc: "Attack roll", + }); + + await render(); + await click("[data-test-copy-bbcode]"); + + assert.true( + writeText.calledWithExactly('[roll="Attack roll"]1d20[/roll]'), + "BBCode with description copied" + ); + }); +}); From a91e0737d60f419dc12d9c56dc7b3771f3286617 Mon Sep 17 00:00:00 2001 From: Steven Chang Date: Fri, 21 Aug 2026 22:14:00 +0000 Subject: [PATCH 13/15] Prettify roll history UI --- .../components/roll-history-entry.gjs | 49 ++++++++++--------- .../components/rolls-post-menu-button.gjs | 2 +- assets/stylesheets/common/index.scss | 37 +++++++++++--- .../components/roll-history-entry-test.gjs | 2 +- 4 files changed, 57 insertions(+), 33 deletions(-) diff --git a/assets/javascripts/discourse/components/roll-history-entry.gjs b/assets/javascripts/discourse/components/roll-history-entry.gjs index 6739558..1db24df 100644 --- a/assets/javascripts/discourse/components/roll-history-entry.gjs +++ b/assets/javascripts/discourse/components/roll-history-entry.gjs @@ -47,24 +47,34 @@ export default class RollHistoryEntry extends Component { }} ...attributes > -
- {{#unless @roll.isCurrent}} - - {{dIcon "far-eye-slash"}} - {{i18n "rollmaster.post.historical"}} +

+ + {{dIcon "rollmaster-dices"}} + {{if @roll.desc @roll.desc (i18n "rollmaster.bbcode.default")}}: + + {{@roll.notation}} + + {{#unless @roll.isCurrent}} + + {{dIcon "far-eye-slash"}} + {{i18n "rollmaster.post.historical"}} + + {{else}} + {{i18n "rollmaster.post.current"}} + {{/unless}} + + {{dAgeWithTooltip @roll.created_at}} - {{else}} - {{i18n "rollmaster.post.current"}} - {{/unless}} - - {{dAgeWithTooltip @roll.created_at}} +

+
+

{{@roll.result}}

- -

- - {{dIcon "rollmaster-dices"}} - {{if @roll.desc @roll.desc (i18n "rollmaster.bbcode.default")}}: - - {{@roll.notation}} -

-

{{@roll.result}}

} diff --git a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs index 6e1bb15..118ad58 100644 --- a/assets/javascripts/discourse/components/rolls-post-menu-button.gjs +++ b/assets/javascripts/discourse/components/rolls-post-menu-button.gjs @@ -23,7 +23,7 @@ export default class RollsPostMenuButton extends Component { get rolls() { return [...(this.args.post.rolls || [])] .sort( - (left, right) => new Date(right.created_at) - new Date(left.created_at) + (left, right) => new Date(left.created_at) - new Date(right.created_at) ) .map((roll) => ({ ...roll, diff --git a/assets/stylesheets/common/index.scss b/assets/stylesheets/common/index.scss index 9f1def3..1ed83cd 100644 --- a/assets/stylesheets/common/index.scss +++ b/assets/stylesheets/common/index.scss @@ -25,7 +25,6 @@ } // Modal - .rollmaster-roll-history-modal { .d-modal__body { max-height: min(70vh, 40rem); @@ -36,7 +35,6 @@ .rollmaster-roll-history { display: flex; flex-direction: column; - gap: 1rem; } .rollmaster-roll-history__empty { @@ -45,17 +43,24 @@ } .rollmaster-roll-history__roll { + .bb-rollmaster-title { + display: flex; + align-items: center; + gap: 0.25rem; + flex-wrap: wrap; + } + &.--historical { opacity: 0.65; } } -.rollmaster-roll-history__roll-controls { +.rollmaster-roll-history__title-meta { + margin-inline-start: auto; display: flex; align-items: center; - justify-content: flex-end; - gap: 0.5rem; - margin-bottom: 0.5rem; + gap: 0.25rem; + flex-shrink: 0; } .rollmaster-roll-history__historical-indicator { @@ -66,5 +71,23 @@ .rollmaster-roll-history__timestamp { color: var(--primary-medium); - font-size: var(--font-down-1); + cursor: pointer; +} + +.rollmaster-roll-history__result-row { + display: flex; + align-items: center; + gap: 0.5rem; + + .bb-rollmaster-results { + flex: 1; + margin-top: 0; + margin-bottom: 0; + } + + .btn { + margin-inline-start: auto; + flex-shrink: 0; + padding: 0.15em; + } } diff --git a/test/javascripts/integration/components/roll-history-entry-test.gjs b/test/javascripts/integration/components/roll-history-entry-test.gjs index e593cd4..6c01d37 100644 --- a/test/javascripts/integration/components/roll-history-entry-test.gjs +++ b/test/javascripts/integration/components/roll-history-entry-test.gjs @@ -26,7 +26,7 @@ module("Integration | Component | RollHistoryEntry", function (hooks) { await render(); assert.dom(".bb-rollmaster-notation").hasText("2d6", "notation is shown"); - assert.dom(".bb-rollmaster-results").hasText("4", "result is shown"); + assert.dom(".bb-rollmaster-results").includesText("4", "result is shown"); }); test("uses default label when no description", async function (assert) { From 2b52db2f1613263e08a8f6bc85273349a78630e8 Mon Sep 17 00:00:00 2001 From: Steven Chang Date: Fri, 21 Aug 2026 22:26:18 +0000 Subject: [PATCH 14/15] Lint update --- .eslintrc.cjs | 1 - .gitignore | 1 + .template-lintrc.cjs | 1 - .../components/roll-history-entry.gjs | 12 +- .../components/rolls-post-menu-button.gjs | 4 +- package.json | 40 +- pnpm-lock.yaml | 4000 ++++++++--------- stylint.config.mjs => stylelint.config.mjs | 0 test/javascripts/acceptance/composer-test.js | 2 +- tsconfig.json | 26 + 10 files changed, 1896 insertions(+), 2191 deletions(-) delete mode 100644 .eslintrc.cjs delete mode 100644 .template-lintrc.cjs rename stylint.config.mjs => stylelint.config.mjs (100%) create mode 100644 tsconfig.json diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index be1a9f3..0000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("@discourse/lint-configs/eslint"); diff --git a/.gitignore b/.gitignore index 74cad9d..905a073 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules /gems /auto_generated +.eslintcache diff --git a/.template-lintrc.cjs b/.template-lintrc.cjs deleted file mode 100644 index 5355ea0..0000000 --- a/.template-lintrc.cjs +++ /dev/null @@ -1 +0,0 @@ -module.exports = require("@discourse/lint-configs/template-lint"); diff --git a/assets/javascripts/discourse/components/roll-history-entry.gjs b/assets/javascripts/discourse/components/roll-history-entry.gjs index 1db24df..fbbcec3 100644 --- a/assets/javascripts/discourse/components/roll-history-entry.gjs +++ b/assets/javascripts/discourse/components/roll-history-entry.gjs @@ -2,9 +2,9 @@ import Component from "@glimmer/component"; import { tracked } from "@glimmer/tracking"; import { action } from "@ember/object"; import { cancel } from "@ember/runloop"; -import DButton from "discourse/components/d-button"; import discourseLater from "discourse/lib/later"; import { clipboardCopy } from "discourse/lib/utilities"; +import DButton from "discourse/ui-kit/d-button"; import dAgeWithTooltip from "discourse/ui-kit/helpers/d-age-with-tooltip"; import dConcatClass from "discourse/ui-kit/helpers/d-concat-class"; import dIcon from "discourse/ui-kit/helpers/d-icon"; @@ -54,7 +54,9 @@ export default class RollHistoryEntry extends Component {
{{@roll.notation}} - {{#unless @roll.isCurrent}} + {{#if @roll.isCurrent}} + {{i18n "rollmaster.post.current"}} + {{else}} {{i18n "rollmaster.post.historical"}} - {{else}} - {{i18n "rollmaster.post.current"}} - {{/unless}} + {{/if}} {{dAgeWithTooltip @roll.created_at}} @@ -74,7 +74,7 @@ export default class RollHistoryEntry extends Component {

{{@roll.result}}

= 22", "npm": "please-use-pnpm", "yarn": "please-use-pnpm", - "pnpm": "9.x" + "pnpm": "^10" }, - "packageManager": "pnpm@9.15.5", - "dependencies": { - "@dice-roller/rpg-dice-roller": "^5.5.1", - "mathjs": "^14.2.0", - "random-js": "^2.1.0" - } + "packageManager": "pnpm@10.28.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09dfcdd..a793842 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,20 +19,32 @@ importers: version: 2.1.0 devDependencies: '@discourse/lint-configs': - specifier: 2.12.0 - version: 2.12.0(ember-template-lint@7.0.4(@babel/core@7.26.10))(eslint@9.24.0)(postcss@8.5.3)(prettier@3.5.3)(stylelint@16.16.0(typescript@5.8.3)) - ember-template-lint: - specifier: 7.0.4 - version: 7.0.4(@babel/core@7.26.10) + specifier: 3.2.0 + version: 3.2.0(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(eslint@10.6.0)(postcss@8.5.26)(prettier@3.8.1)(stylelint@17.5.0(typescript@5.9.3)) + '@glint/ember-tsc': + specifier: 1.8.11 + version: 1.8.11(typescript@5.9.3) + concurrently: + specifier: ^9.2.3 + version: 9.2.4 + discourse: + specifier: npm:@discourse/types@2026.3.0-d02b2966 + version: '@discourse/types@2026.3.0-d02b2966' eslint: - specifier: 9.24.0 - version: 9.24.0 + specifier: 10.6.0 + version: 10.6.0 + lint-to-the-future: + specifier: ^2.6.4 + version: 2.6.4 + lint-to-the-future-eslint: + specifier: ^3.3.0 + version: 3.3.0(eslint@10.6.0) prettier: - specifier: 3.5.3 - version: 3.5.3 + specifier: 3.8.1 + version: 3.8.1 stylelint: - specifier: 16.16.0 - version: 16.16.0(typescript@5.8.3) + specifier: 17.5.0 + version: 17.5.0(typescript@5.9.3) packages: @@ -44,38 +56,64 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@8.0.0': + resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/compat-data@7.26.5': resolution: {integrity: sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==} engines: {node: '>=6.9.0'} + '@babel/compat-data@8.0.0': + resolution: {integrity: sha512-DOjnob/cXOUgDOozCDeq/aK2p5y8dUIVdf6tNhEV1HQRd6I8aQ4f4fbtHRVEvb6lP3BGomrKHiS8ICAASSVQSw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/core@7.26.10': resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} engines: {node: '>=6.9.0'} - '@babel/eslint-parser@7.27.0': - resolution: {integrity: sha512-dtnzmSjXfgL/HDgMcmsLSzyGbEosi4DrGWoCNfuI+W4IkVJw6izpTe7LtOdwAXnkDqw5yweboYCTkM2rQizCng==} - engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} + '@babel/core@8.0.1': + resolution: {integrity: sha512-5FgxM4dLQpMJHSiVATk8foW263dVHQHBVpXYiimNECVWG01f4nFyEbQixeT6Mwvg7TayREJ2gpKl3o2RoMdnqw==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@babel/eslint-parser@8.0.1': + resolution: {integrity: sha512-2javO8pAQv/ld6sS6OcxoLAlzZEZy+xm99bnoAfMhzKSumKhdF5wylpbZB7XTorWr3KLPtx5K95eduJPOy1mzA==} + engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: - '@babel/core': ^7.11.0 - eslint: ^7.5.0 || ^8.0.0 || ^9.0.0 + '@babel/core': ^8.0.0 + eslint: ^9.0.0 || ^10.0.0 '@babel/generator@7.27.0': resolution: {integrity: sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==} engines: {node: '>=6.9.0'} + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@8.0.0': + resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-annotate-as-pure@7.25.9': resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} + '@babel/helper-annotate-as-pure@8.0.0': + resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-compilation-targets@7.26.5': resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.25.9': - resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/helper-compilation-targets@8.0.0': + resolution: {integrity: sha512-JwculLABZvyPvyLBpwU/E/IbH2uM3mnxNtIJpxnIfb24y1PrdVxK5Dqjle4DpgqpGRnwgC7G8IkzPdSXZrO1Ew==} + engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-create-class-features-plugin@7.27.0': resolution: {integrity: sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==} @@ -83,10 +121,28 @@ packages: peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-create-class-features-plugin@8.0.1': + resolution: {integrity: sha512-++t3ZktzlLmASAxIlxeXQK9Z2YwUafYGYcvGBFevqOqt16HozVHStUoQvWD09fzAZOb/uJGpUTBuGK41AJAuOA==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@8.0.0': + resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-member-expression-to-functions@7.25.9': resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@8.0.0': + resolution: {integrity: sha512-xkXrMbtk87Gk7+oKBVmBc6EORg/Qwx++AHESldmHkpvG8wgccdhJJFwrzqlF382Fk8wfXhJHWE/g/43QvEGNPQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-module-imports@7.25.9': resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} engines: {node: '>=6.9.0'} @@ -101,216 +157,312 @@ packages: resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} engines: {node: '>=6.9.0'} + '@babel/helper-optimise-call-expression@8.0.0': + resolution: {integrity: sha512-3W6satvtPuCUkUx63S2jMoW9EQNYkADgs1HTfufmL7gCmAulHMKupA/12WNz4A0GMMFn/YnWWwqOT9IZrJHQjg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-plugin-utils@7.26.5': resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} + '@babel/helper-plugin-utils@8.0.1': + resolution: {integrity: sha512-3PKFgjTyPlhFhorfP+SjKQxLViIL++zWjFOO4hGriYU+Bsm983DxEM1JmDRJVWXV0O9npu+xXRqz7Pbd3mh70g==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-replace-supers@7.26.5': resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 + '@babel/helper-replace-supers@8.0.1': + resolution: {integrity: sha512-B1SZADIcy3tmH8CmWvj4SHi/oAPom4UL3uknTc2QRNsPVLFk/sPnZvQL/8kj7Y5omvjMqie0vklvs6XM4OLW5Q==} + engines: {node: ^22.18.0 || >=24.11.0} + peerDependencies: + '@babel/core': ^8.0.0 + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} engines: {node: '>=6.9.0'} + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + resolution: {integrity: sha512-xmCA9kP3IhySsqhzwIdWGlDN/1A4cCKNBO/uwZx/3YzmDoMePwno2Q5/Bq0q+tYaKbeF940YiKV/kaW8Mzvpjw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-string-parser@7.25.9': resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-identifier@7.25.9': resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@8.0.4': + resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-option@7.25.9': resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@8.0.0': + resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helpers@7.27.0': resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.7': - resolution: {integrity: sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==} - engines: {node: '>=6.0.0'} - hasBin: true + '@babel/helpers@8.0.0': + resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==} + engines: {node: ^22.18.0 || >=24.11.0} '@babel/parser@7.27.0': resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.8': + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@8.0.4': + resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + '@babel/plugin-proposal-decorators@7.25.9': resolution: {integrity: sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-decorators@7.25.9': - resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==} - engines: {node: '>=6.9.0'} + '@babel/plugin-proposal-decorators@8.0.2': + resolution: {integrity: sha512-+C6O6KKXU7BBq1GNaIkFJxrALUVGRcr+WeWm4OcuRl3h+l/CmNfcTLMrT2Lm3uvGBimBH/8pEBRrXJFLoO67Gg==} + engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^8.0.0 - '@babel/plugin-syntax-typescript@7.25.9': - resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + '@babel/plugin-syntax-decorators@7.25.9': + resolution: {integrity: sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.27.0': - resolution: {integrity: sha512-fRGGjO2UEGPjvEcyAZXRXAS8AfdaQoq7HnxAbJoAoW10B9xOKesmmndJv+Sym2a+9FHWZ9KbyyLCe9s0Sn5jtg==} - engines: {node: '>=6.9.0'} + '@babel/plugin-syntax-decorators@8.0.1': + resolution: {integrity: sha512-NI+0S/6MvR6GlcQFwjDZ+WIc2qvG6TXN534lYs9llNldwW4b7Dh6KTtk030FA0xWdYGs4t1lWo+OEWN8wGB+Nw==} + engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: - '@babel/core': ^7.0.0-0 + '@babel/core': ^8.0.0 '@babel/runtime@7.27.0': resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} engines: {node: '>=6.9.0'} - '@babel/template@7.25.9': - resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} - engines: {node: '>=6.9.0'} - '@babel/template@7.27.0': resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.26.7': - resolution: {integrity: sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==} + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/traverse@7.27.0': resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.7': - resolution: {integrity: sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==} + '@babel/traverse@7.29.8': + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} engines: {node: '>=6.9.0'} + '@babel/traverse@8.0.4': + resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/types@7.27.0': resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} engines: {node: '>=6.9.0'} - '@csstools/css-parser-algorithms@3.0.4': - resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} - engines: {node: '>=18'} + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@babel/types@8.0.4': + resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} + engines: {node: ^22.18.0 || >=24.11.0} + + '@cacheable/memory@2.2.0': + resolution: {integrity: sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==} + + '@cacheable/utils@2.5.0': + resolution: {integrity: sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==} + + '@csstools/css-calc@3.3.0': + resolution: {integrity: sha512-c5ihYsPkdG6JCkU2zTMm4+k6r7RXuGxtWYhu5DHMIiF1FHzrfmHL5so11AoFpUv/tu61xfcmT4AmKoFfMPoqdQ==} + engines: {node: '>=20.19.0'} peerDependencies: - '@csstools/css-tokenizer': ^3.0.3 + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-tokenizer@3.0.3': - resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} - engines: {node: '>=18'} + '@csstools/css-parser-algorithms@4.0.0': + resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-tokenizer': ^4.0.0 - '@csstools/media-query-list-parser@4.0.2': - resolution: {integrity: sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==} - engines: {node: '>=18'} + '@csstools/css-syntax-patches-for-csstree@1.1.8': + resolution: {integrity: sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg==} peerDependencies: - '@csstools/css-parser-algorithms': ^3.0.4 - '@csstools/css-tokenizer': ^3.0.3 + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true - '@csstools/selector-specificity@5.0.0': - resolution: {integrity: sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==} - engines: {node: '>=18'} + '@csstools/css-tokenizer@4.0.0': + resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} + engines: {node: '>=20.19.0'} + + '@csstools/media-query-list-parser@5.0.0': + resolution: {integrity: sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/selector-resolve-nested@4.0.1': + resolution: {integrity: sha512-j3vdQu0XwLME5qOTWxm8cnmvsf423R2YL6DbKklCHZwkDm7UdKNu6RPlw4REIJhSlKBICY3B70/7QZdicLqZgg==} + engines: {node: '>=20.19.0'} + peerDependencies: + postcss-selector-parser: ^7.1.1 + + '@csstools/selector-specificity@6.0.0': + resolution: {integrity: sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==} + engines: {node: '>=20.19.0'} peerDependencies: - postcss-selector-parser: ^7.0.0 + postcss-selector-parser: ^7.1.1 '@dice-roller/rpg-dice-roller@5.5.1': resolution: {integrity: sha512-De5/UTjihpv639XJDBOCfwuOlzIInLqCeal5rpIY9C8Qh8oaNL2/5e0wa/0lcVZyy8m+BCn5zT4eZamCnguIXQ==} engines: {node: '>=18.0'} - '@discourse/lint-configs@2.12.0': - resolution: {integrity: sha512-5VFk4wCIhJ/CcfytNCnsMZnzQ30MtOtNHff4suGu/Bgw+WLvtVupp0SxmcU4sNIz4IQRsS1q0dKn50crEcUcBQ==} + '@discourse/lint-configs@3.2.0': + resolution: {integrity: sha512-mEZYPNlGyf+Jq6i6QKzi2mXw9ofgcEh1XARoQKQS1Y+SsclJgGHT33MUxn5QwWEaGpSYA67/0hdPVL+HEW29gw==} peerDependencies: - ember-template-lint: 7.0.1 - eslint: 9.22.0 - prettier: 3.5.3 - stylelint: 16.16.0 + eslint: 10.6.0 + prettier: 3.8.1 + stylelint: 17.5.0 - '@dual-bundle/import-meta-resolve@4.1.0': - resolution: {integrity: sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==} + '@discourse/types@2026.3.0-d02b2966': + resolution: {integrity: sha512-TzgaVI0serxgv3/ebc1or0MRJIDRMYhTd+B9gA7HTsAZmMGCRPrrxYeqD5TAkZurL5Tj1o6fP5Jk6mbyFm5Qwg==} + engines: {node: '>= 20', npm: please-use-pnpm, pnpm: ^10, yarn: please-use-pnpm} '@ember-data/rfc395-data@0.0.4': resolution: {integrity: sha512-tGRdvgC9/QMQSuSuJV45xoyhI0Pzjm7A9o/MVVA3HakXIImJbbzx/k/6dO9CUEQXIyS2y0fW6C1XaYOG7rY0FQ==} + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - '@eslint-community/regexpp@4.12.1': - resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/config-array@0.20.0': - resolution: {integrity: sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.2.1': - resolution: {integrity: sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.12.0': - resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/core@0.13.0': - resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/config-helpers@0.6.0': + resolution: {integrity: sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/eslintrc@3.3.1': - resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/js@9.24.0': - resolution: {integrity: sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/js@10.0.1': + resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true - '@eslint/object-schema@2.1.6': - resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.2.8': - resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@glimmer/env@0.1.7': resolution: {integrity: sha512-JKF/a9I9jw6fGoz8kA7LEQslrwJ5jms5CXhu/aqkBWk+PmZ6pTl8mlb/eJ/5ujBGTiQzBhy5AIWF712iA+4/mw==} - '@glimmer/global-context@0.84.3': - resolution: {integrity: sha512-8Oy9Wg5IZxMEeAnVmzD2NkObf89BeHoFSzJgJROE/deutd3rxg83mvlOez4zBBGYwnTb+VGU2LYRpet92egJjA==} + '@glimmer/interfaces@0.94.6': + resolution: {integrity: sha512-sp/1WePvB/8O+jrcUHwjboNPTKrdGicuHKA9T/lh0vkYK2qM5Xz4i25lQMQ38tEMiw7KixrjHiTUiaXRld+IwA==} - '@glimmer/interfaces@0.84.3': - resolution: {integrity: sha512-dk32ykoNojt0mvEaIW6Vli5MGTbQo58uy3Epj7ahCgTHmWOKuw/0G83f2UmFprRwFx689YTXG38I/vbpltEjzg==} + '@glimmer/syntax@0.95.0': + resolution: {integrity: sha512-W/PHdODnpONsXjbbdY9nedgIHpglMfOzncf/moLVrKIcCfeQhw2vG07Rs/YW8KeJCgJRCLkQsi+Ix7XvrurGAg==} - '@glimmer/interfaces@0.92.3': - resolution: {integrity: sha512-QwQeA01N+0h+TAi/J7iUnZtRuJy+093hNyagxDQBA6b1wCBw+q+al9+O6gmbWlkWE7EifzmNE1nnrgcecJBlJQ==} + '@glimmer/util@0.94.8': + resolution: {integrity: sha512-HfCKeZ74clF9BsPDBOqK/yRNa/ke6niXFPM6zRn9OVYw+ZAidLs7V8He/xljUHlLRL322kaZZY8XxRW7ALEwyg==} - '@glimmer/reference@0.84.3': - resolution: {integrity: sha512-lV+p/aWPVC8vUjmlvYVU7WQJsLh319SdXuAWoX/SE3pq340BJlAJiEcAc6q52y9JNhT57gMwtjMX96W5Xcx/qw==} + '@glimmer/wire-format@0.94.8': + resolution: {integrity: sha512-A+Cp5m6vZMAEu0Kg/YwU2dJZXyYxVJs2zI57d3CP6NctmX7FsT8WjViiRUmt5abVmMmRH5b8BUovqY6GSMAdrw==} - '@glimmer/syntax@0.84.3': - resolution: {integrity: sha512-ioVbTic6ZisLxqTgRBL2PCjYZTFIwobifCustrozRU2xGDiYvVIL0vt25h2c1ioDsX59UgVlDkIK4YTAQQSd2A==} - - '@glimmer/syntax@0.92.3': - resolution: {integrity: sha512-7wPKQmULyXCYf0KvbPmfrs/skPISH2QGR9atCnmDWnHyLv5SSZVLm1P0Ctrpta6+Ci3uGQb7hGk0IjsLEavcYQ==} - - '@glimmer/util@0.84.3': - resolution: {integrity: sha512-qFkh6s16ZSRuu2rfz3T4Wp0fylFj3HBsONGXQcrAdZjdUaIS6v3pNj6mecJ71qRgcym9Hbaq/7/fefIwECUiKw==} - - '@glimmer/util@0.92.3': - resolution: {integrity: sha512-K1oH93gGU36slycxJ9CcFpUTsdOc4XQ6RuZFu5oRsxFYtEF5PSu7ik11h58fyeoaWOr1ebfkyAMawbeI2AJ5GA==} - - '@glimmer/validator@0.84.3': - resolution: {integrity: sha512-RTBV4TokUB0vI31UC7ikpV7lOYpWUlyqaKV//pRC4pexYMlmqnVhkFrdiimB/R1XyNdUOQUmnIAcdic39NkbhQ==} + '@glint/ember-tsc@1.8.11': + resolution: {integrity: sha512-Dj5OAMFwckQ05b0zy/3h750/+hnaM/ef0423U2LdIafw8Ie2yx2zKWK6X0s/mN136VCEPBbMsn9qhg+vBXBEog==} + hasBin: true + peerDependencies: + ember-source: '>=3.28.0' + typescript: '>=5.6.0' + peerDependenciesMeta: + ember-source: + optional: true - '@glimmer/wire-format@0.92.3': - resolution: {integrity: sha512-gFz81Q9+V7Xs0X8mSq6y8qacHm0dPaGJo2/Bfcsdow1hLOKNgTCLr4XeDBhRML8f6I6Gk9ugH4QDxyIOXOpC4w==} + '@glint/template@1.7.8': + resolution: {integrity: sha512-n8ymxa60inoSKh2BqfHP2eTtmaXgr08mgPKTAujkzD/Ix1cBcTYv0am0FQ5ei3XFprDbrz2OBAF14BmvfoOnVA==} - '@handlebars/parser@2.0.0': - resolution: {integrity: sha512-EP9uEDZv/L5Qh9IWuMUGJRfwhXJ4h1dqKTT4/3+tY0eu7sPis7xh23j61SYUnNF4vqCQvvUXpDo9Bh/+q1zASA==} + '@handlebars/parser@2.2.2': + resolution: {integrity: sha512-n/SZW+12rwikx/f8YcSv9JCi5p9vn1Bnts9ZtVvfErG4h0gbjHI1H1ZMhVUnaOC7yzFc6PtsCKIK8XeTnL90Gw==} + engines: {node: ^18 || ^20 || ^22 || >=24} '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -332,6 +484,9 @@ packages: resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} engines: {node: '>=18.18'} + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + '@jridgewell/gen-mapping@0.3.8': resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} engines: {node: '>=6.0.0'} @@ -350,15 +505,24 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} - '@keyv/serialize@1.0.3': - resolution: {integrity: sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==} + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@keyv/bigmap@1.3.1': + resolution: {integrity: sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==} + engines: {node: '>= 18'} + peerDependencies: + keyv: ^5.6.0 - '@lint-todo/utils@13.1.1': - resolution: {integrity: sha512-F5z53uvRIF4dYfFfJP3a2Cqg+4P1dgJchJsFnsZE0eZp0LK8X7g2J0CsJHRgns+skpXOlM7n5vFGwkWCWj8qJg==} - engines: {node: 12.* || >= 14} + '@keyv/serialize@1.1.1': + resolution: {integrity: sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==} - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': - resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} + '@napi-rs/wasm-runtime@1.2.3': + resolution: {integrity: sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -372,8 +536,130 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@one-ini/wasm@0.2.1': + resolution: {integrity: sha512-TUqERXGNTifZ9y2g3wPxQrw3HpHv/02DsW3D90T9x0hhonrL1ZqpSmNrU2XkoIq0fP1N6gZfVQzy2Fw1ZvGBNg==} + + '@oxc-parser/binding-android-arm-eabi@0.130.0': + resolution: {integrity: sha512-h/xYU8/7ADWzVSf5I+YalLpj33LOy9CI/zgbJNIZ5eunRBG+Czqa3lZsvuPHHf3rOt6z1c5+UzoxjbAzAvhwVw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxc-parser/binding-android-arm64@0.130.0': + resolution: {integrity: sha512-oFWFJrsGv9siFM4HjMqKNB7IuIZD/SMmZdCXl8xyx7lDplGvPKyewpOo272rSWgMXe2Wx7bWI0Yj+gkHv4qbeg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxc-parser/binding-darwin-arm64@0.130.0': + resolution: {integrity: sha512-sGUzupdTplK9jQg7eJZ878HfEgQjJNBc6dAYVWJ9W5aU+J8rLfRJhTVsKThiu1pNwm6Y1qKCcbC6WhNWSXR3Ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxc-parser/binding-darwin-x64@0.130.0': + resolution: {integrity: sha512-PsB4cdCISbC00Uy8eiD8bc2AkGWjZqrSrJnkBFuG2ptrrf6mZ2F5gLFSjOAVMMgZPg8B1D7OydJwLWSfyI2Plg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxc-parser/binding-freebsd-x64@0.130.0': + resolution: {integrity: sha512-DgABp3l38hS77JbXCV4qk1+n6DPym5u8zzwuweokezm2tX194nDSJDENbDRECxVsiNbprKATLbk+Z5wlHT0OHw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxc-parser/binding-linux-arm-gnueabihf@0.130.0': + resolution: {integrity: sha512-4Kn3CTEmwFrzhTSC/JuUW16qovmaMdX7jeSKbL8w0pLtLww7To1a2XJi9Z5uD8QWUkfUHhqfV+VD6dVzBnWzoA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm-musleabihf@0.130.0': + resolution: {integrity: sha512-D35KZM3F4rRu1uAFKyBlg3Gaf/ybCjyaPR1hfgvk5ex8NtcTmRgc0JgSighEyNg96TPrFhemFba68SZuxaha8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxc-parser/binding-linux-arm64-gnu@0.130.0': + resolution: {integrity: sha512-Q9o7oVlo955KHwS8l1u0bCzIx+JsZUA3XToLXC+MsMhye/9LeBQbt84nh120cl2XLy+TEzvugYDiHShg5yaX6Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-arm64-musl@0.130.0': + resolution: {integrity: sha512-EiJ/gC0ljbcwVpycC8YWw6ggMbtsPX8XMOt0mPx0aqWeMsNR+L9m05Flbvd5T+GlivG+GkSWQL7tM9SRFpM/dw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + + '@oxc-parser/binding-linux-ppc64-gnu@0.130.0': + resolution: {integrity: sha512-b+h/lsLLurp756dMGizNs5uPaJfyEdWrTcV5t8M609jWm1DEHB1StpRXCkyvwtkJx3m+qL5BNQ0dEKan/4yGFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + + '@oxc-parser/binding-linux-riscv64-gnu@0.130.0': + resolution: {integrity: sha512-O19Cil83XAyjEFfo8WhkMwY58ALqZ7ckjGL+25mjMIuF84urWBeANH0FC8B8BsSSygWU3/1aY3ADdDbp+wlBnw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxc-parser/binding-linux-riscv64-musl@0.130.0': + resolution: {integrity: sha512-BgXRVC0+83n3YzCscLQjj6nbyeBIVeZYPTI4fFMAE4WNm2+4RXhWp03IVizL7esIz36kgmT48aebk1iM+cs8sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + + '@oxc-parser/binding-linux-s390x-gnu@0.130.0': + resolution: {integrity: sha512-6tJz0xvnGhsokE7N1WlUSBXibpYmT9xSJFS1Ce41Km/+8gQvdlW8MLhRv8PD0L7ix8vRG0FDDepp3jdOFzdVdw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + + '@oxc-parser/binding-linux-x64-gnu@0.130.0': + resolution: {integrity: sha512-9aCWj83dp3heTQGmGnZGdIWgxjZrr/7VQ0TGFHH5PKByxJKF2Hcr4qvaSUHhhGEa3MSsDjTL1YDP8RAgdL5/Cg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-linux-x64-musl@0.130.0': + resolution: {integrity: sha512-afXt87aZBqrUVli8TB/I8H1G50RDWcwirjWtXGXYqJ2ZqWEiErH7V72j3LUSDZaivmtu2OLX0KQ/mbhP81mr7A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + + '@oxc-parser/binding-openharmony-arm64@0.130.0': + resolution: {integrity: sha512-I0NCrZV/YZuCGWgqwNN/GO/iXlLF2z+Wgc7u+Aa9N4P51oYeIa0XT+zVBUne4csO9GqxskXgI4g8JzzWGRpfOw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@oxc-parser/binding-wasm32-wasi@0.130.0': + resolution: {integrity: sha512-sJgQkGaBX0WJvPUDfwciex6IcTk5O5NLQ1bhEb6f3nBruh1GshKMRSMt2bxZlYrgBzjyBbJzsnO+InPG0bg+fA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.130.0': + resolution: {integrity: sha512-bjcma99sQrNh6RY4mPO9yTkfxql6TDFoN3HWdK31RCKXwNhcDgJXW/l8PUtzKNiQ+9vpKJfJtQq+LklBuxSOBA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@oxc-parser/binding-win32-ia32-msvc@0.130.0': + resolution: {integrity: sha512-hRYbv6HhpSTzT4xTiIkadLI7upLQxuOdLPR/9nL1fTjwhgutBTPXrwaAPb/jTFVx6/8C7Jb5HcUKhmNwloTbFA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + + '@oxc-parser/binding-win32-x64-msvc@0.130.0': + resolution: {integrity: sha512-RBpA9TsRucJq6HNVNCFF1iKg+QeTkLdZf7hi4xaOGCPvMZWvDHjQgSOEZMUpuW4JNciHbxNhLEYmz5CVygjVGQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@oxc-project/types@0.130.0': + resolution: {integrity: sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==} '@simple-dom/interface@1.4.0': resolution: {integrity: sha512-l5qumKFWU0S+4ZzMaLXFU8tQZsicHEMEyAxI5kDFGhJsRqDwe0a7/iPA/GdxlGyDKseQQAgIz5kzU7eXTrlSpA==} @@ -382,30 +668,128 @@ packages: resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} engines: {node: '>=18'} - '@types/eslint@8.56.12': - resolution: {integrity: sha512-03ruubjWyOHlmljCVoxSuNDdmfZDzsrrz0P2LeJsOXr+ZwFQ+0yQIwNCwt/GYhV7Z31fgtXJTAEs+FYlEL851g==} + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/gensync@1.0.5': + resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} + + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@typescript-eslint/eslint-plugin@8.67.0': + resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.67.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.67.0': + resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.67.0': + resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.67.0': + resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.67.0': + resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.67.0': + resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.67.0': + resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.67.0': + resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.67.0': + resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.67.0': + resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@volar/kit@2.4.28': + resolution: {integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==} + peerDependencies: + typescript: '*' + + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} + + '@volar/language-server@2.4.28': + resolution: {integrity: sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==} + + '@volar/language-service@2.4.28': + resolution: {integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==} + + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} + + '@volar/test-utils@2.4.28': + resolution: {integrity: sha512-N7RNiHHDPtqK5B21x4W462XMQj7Z75ynN3isLP+3Rb44hbJjhxxDxzs+QqWB0sjM57EtTJga+SDd9WWy3OjMzA==} + + '@volar/typescript@2.4.28': + resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} + + '@vscode/l10n@0.0.18': + resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} engines: {node: '>=0.4.0'} hasBin: true - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -414,6 +798,10 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.3.0: + resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} @@ -425,70 +813,21 @@ packages: resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} engines: {node: '>= 0.4'} - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - - array-includes@3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} - engines: {node: '>= 0.4'} - - array-union@2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} - - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} - astral-regex@2.0.0: resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} engines: {node: '>=8'} - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} - - async-promise-queue@1.0.5: - resolution: {integrity: sha512-xi0aQ1rrjPWYmqbwr18rrSKbSaXIeIwSd1J4KAgVfkq8utNbdZoht7GfvfY6swFUAMJ9obkc4WPJmtGwl+B8dw==} - - async@2.6.4: - resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} - - at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} - balanced-match@2.0.0: - resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} - - base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - - bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -499,34 +838,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - - buffer@6.0.3: - resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - - cacheable@1.8.10: - resolution: {integrity: sha512-0ZnbicB/N2R6uziva8l6O6BieBklArWyiGx4GkwAhLKhSHyQtRfM9T1nx7HHuHDKkYB/efJQhz3QJ6x/YqoZzA==} - - call-bind-apply-helpers@1.0.1: - resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} - engines: {node: '>= 0.4'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.8: - resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} - engines: {node: '>= 0.4'} - - call-bound@1.0.3: - resolution: {integrity: sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + cacheable@2.5.0: + resolution: {integrity: sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} @@ -539,30 +852,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.4.1: - resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} - engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} - - ci-info@4.1.0: - resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==} - engines: {node: '>=8'} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -573,35 +866,30 @@ packages: colord@2.9.3: resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} - colors@1.4.0: - resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} - engines: {node: '>=0.1.90'} + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} complex.js@2.4.2: resolution: {integrity: sha512-qtx7HRhPGSCBtGiST4/WGHuW+zeaND/6Ld+db6PbrulIB1i2Ev/2UPiqcmpQNPSyfBKraC0EOvOKCB5dGZKt3g==} - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - content-tag-utils@0.3.1: - resolution: {integrity: sha512-uBAmklAxqmem7WX/F7YA4eWBTegGLJ93MOPSJaJliAuzTNgF3u/H9YLlJ6Nae9/FwV+037OuXc75hvcmub1qww==} - engines: {node: '>= 18'} - - content-tag@2.0.3: - resolution: {integrity: sha512-htLIdtfhhKW2fHlFLnZH7GFzHSdSpHhDLrWVswkNiiPMZ5uXq5JfrGboQKFhNQuAAFF8VNB2EYUj3MsdJrKKpg==} + concurrently@9.2.4: + resolution: {integrity: sha512-TZ0CEhyzvFjgtAvHTusDMgj7wNdihCh7LLLrzdUOXIhdlnL2JBBGA9eJxR24rtqgmdjh3OA3hrN1rCHj6HM8qA==} + engines: {node: '>=18'} + hasBin: true - content-tag@3.1.2: - resolution: {integrity: sha512-Z+MGhZfnFFKzYC+pUTWXnoDYhfiXP9ojZe3JbwsYufmDuoeq2EvuDyeFAJ/RnKokUwz5s9bQhDOrbvSYRShcrQ==} + content-tag@4.2.0: + resolution: {integrity: sha512-f/o+F3qSa4gg23I7RWy6cMDxP2nPo99YWusxw2bjne7ZC6Acqqf4uB/+87AekOq1ehTocHH7b7nMd2X4S3NHVw==} convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cosmiconfig@9.0.0: - resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} + cosmiconfig@9.0.2: + resolution: {integrity: sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -613,34 +901,23 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - css-functions-list@3.2.3: - resolution: {integrity: sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==} - engines: {node: '>=12 || >=16'} + css-functions-list@3.3.3: + resolution: {integrity: sha512-8HFEBPKhOpJPEPu70wJJetjKta86Gw9+CCyCnB3sui2qQfOvRyqBy4IKLKKAwdMpWb2lHXWk9Wb4Z6AmaUT1Pg==} + engines: {node: '>=12'} css-tree@3.1.0: resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} hasBin: true - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - date-fns@3.6.0: - resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} - debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -649,16 +926,17 @@ packages: supports-color: optional: true - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} peerDependencies: supports-color: '*' peerDependenciesMeta: supports-color: optional: true - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -672,61 +950,42 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - dir-glob@3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dot-case@3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} + editorconfig@3.0.2: + resolution: {integrity: sha512-T0ix8GhtxyKVfUFEcvdNDt3YGqlwkFHbD4/5bgFUDgFmxhI/cSRAeJ87/Sz//Cq8Eam6JX/e23RkoFO71P7aAA==} + engines: {node: '>=20'} + hasBin: true electron-to-chromium@1.5.93: resolution: {integrity: sha512-M+29jTcfNNoR9NV7la4SwUqzWAxEwnc7ThA5e1m6LRSotmpfpCpLcIfgtSCVL+MllNLgAyM/5ru86iMRemPzDQ==} - ember-eslint-parser@0.5.9: - resolution: {integrity: sha512-IW4/3cEiFp49M2LiKyzi7VcT1egogOe8UxQ9eUKTooenC7Q4qNhzTD6rOZ8j51m8iJC+8hCzjbNCa3K4CN0Hhg==} + ember-eslint-parser@0.14.6: + resolution: {integrity: sha512-Z4fA1E/3uGZeBLPcz5aCiic3OoZ9YVxQBkImgGXdtgHLLuF/51drGor/FCwT9cCs1XZqY8HWRy4aarl+MZCfwQ==} engines: {node: '>=16.0.0'} peerDependencies: - '@babel/core': ^7.23.6 + '@babel/eslint-parser': ^7.28.6 || ^8.0.0 '@typescript-eslint/parser': '*' peerDependenciesMeta: + '@babel/eslint-parser': + optional: true '@typescript-eslint/parser': optional: true + ember-estree@0.6.11: + resolution: {integrity: sha512-aZyheQGUXyHu8GARPd1YyjbDMGkvqBYKzPj6RVp8qqMqA1L1MbkWKsljWE3K1CwiJcHwTPgm/O3oxS0TY1AX9Q==} + ember-rfc176-data@0.3.18: resolution: {integrity: sha512-JtuLoYGSjay1W3MQAxt3eINWXNYYQliK90tLwtb8aeCuQK8zKGCRbBodVIrkcTqshULMnRuTOS6t1P7oQk3g6Q==} - ember-template-lint@7.0.4: - resolution: {integrity: sha512-60TAoopPzfSpfCEQawnOFUTxizFAZkar6f/0Nsa1FeAIxif6oBqY+tVVrqwcOSenVLjWZLMGxm4iARlQz2aagg==} - engines: {node: ^18.18.0 || >= 20.9.0} - hasBin: true - - ember-template-recast@6.1.5: - resolution: {integrity: sha512-VnRN8FzEHQnw/5rCv6Wnq8MVYXbGQbFY+rEufvWV+FO/IsxMahGEud4MYWtTA2q8iG+qJFrDQefNvQ//7MI7Qw==} - engines: {node: 12.* || 14.* || >= 16.*} - hasBin: true - emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + engines: {node: '>=14'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -734,34 +993,6 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-abstract@1.23.9: - resolution: {integrity: sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} - escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -773,89 +1004,46 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - eslint-formatter-kakoune@1.0.0: - resolution: {integrity: sha512-Uk/TVLt6Nf6Xoz7C1iYuZjOSdJxe5aaauGRke8JhKeJwD66Y61/pY2FjtLP04Ooq9PwV34bzrkKkU2UZ5FtDRA==} - - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} - - eslint-module-utils@2.12.0: - resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-decorator-position@6.0.0: - resolution: {integrity: sha512-AUbZbt3JXnmP7Typfba4BIEFkSCc2rA6BkutsYiywIcEoX/yRL7jzqAp4UMpSDNhCMUUAfGt48k3141PhKC07w==} + eslint-plugin-decorator-position@6.1.1: + resolution: {integrity: sha512-ubUyPxDvD/bnnZdeTFiP6cOYPFk9hYPR73jTaz/iXJ6iqpP8xGBYnFVjMj+dkObD5/HLTxxYA4pkn1ndt9dXSg==} engines: {node: '>=14'} peerDependencies: - '@babel/eslint-parser': ^7.18.2 - eslint: ^7.31.0 || ^8.0.0 || ^9.0.0 + '@babel/eslint-parser': ^7.18.2 || ^8.0.0 + eslint: ^7.31.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: '@babel/eslint-parser': optional: true - eslint-plugin-ember@12.5.0: - resolution: {integrity: sha512-DBUzsaKWDVXsujAZPpRir0O7owdlCoVzZmtaJm7g7iQeSrNtcRWI7AItsTqKSsws1XeAySH0sPsQItMdDCb9Fg==} - engines: {node: 18.* || 20.* || >= 21} + eslint-plugin-ember@13.5.0: + resolution: {integrity: sha512-q1s/irrc2l1KeE1l5S1UiO7ZrvGF5aYm903CMQ7lHFc09F/78/uvgzvA4wPZ9TFMl07r2ttoIINrEOFy05RtGg==} + engines: {node: '>= 20.19'} peerDependencies: '@typescript-eslint/parser': '*' - eslint: '>= 8' + eslint: '>= 8.40.0' peerDependenciesMeta: '@typescript-eslint/parser': optional: true - eslint-plugin-import@2.31.0: - resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-qunit@8.1.2: - resolution: {integrity: sha512-2gDQdHlQW8GVXD7YYkO8vbm9Ldc60JeGMuQN5QlD48OeZ8znBvvoHWZZMeXjvoDPReGaLEvyuWrDtrI8bDbcqw==} + eslint-plugin-qunit@8.2.6: + resolution: {integrity: sha512-S1jC/DIW9J8VtNX4uG1vlf5FZVrfQFlcuiYmvTHR2IICUhubHqpWA5o+qS1tujh+81Gs39omKV2D4OXfbSJE5g==} engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} + peerDependencies: + eslint: '>=8.38.0' - eslint-plugin-simple-import-sort@12.1.1: - resolution: {integrity: sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA==} + eslint-plugin-simple-import-sort@13.0.0: + resolution: {integrity: sha512-McAc+/Nlvcg4byY/CABGH8kqnefWBj8s3JA2okEtz8ixbECQgU46p0HkTUKa4YS7wvgGceimlc34p1nXqbWqtA==} peerDependencies: eslint: '>=5.0.0' - eslint-plugin-sort-class-members@1.21.0: - resolution: {integrity: sha512-QKV4jvGMu/ge1l4s1TUBC6rqqV/fbABWY7q2EeNpV3FRikoX6KuLhiNvS8UuMi+EERe0hKGrNU9e6ukFDxNnZQ==} + eslint-plugin-sort-class-members@1.22.1: + resolution: {integrity: sha512-TC76+m06fjpiAYPrEcyyvvWzp1aMHNBVGROLu9ijQuPDZPWJjhNTheha4f6f7eUTWabloczLZagoZ+mb6Cv0ZQ==} engines: {node: '>=4.0.0'} peerDependencies: eslint: '>=0.8.0' - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - eslint-scope@7.2.2: - resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - - eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} eslint-utils@3.0.0: resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} @@ -871,13 +1059,13 @@ packages: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@9.24.0: - resolution: {integrity: sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint@10.6.0: + resolution: {integrity: sha512-6lVbcqSodALYo+4ELD0heG6lFiFxnLMuLkiMi2qV8LMp54N8tE8FT1GMH+ev4Ti00nFjNze2+Su6DsV5OQW3Dg==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: jiti: '*' @@ -885,22 +1073,18 @@ packages: jiti: optional: true - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} - esquery@1.6.0: - resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} engines: {node: '>=0.10'} esrecurse@4.3.0: resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} engines: {node: '>=4.0'} - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -932,8 +1116,17 @@ packages: fastq@1.19.0: resolution: {integrity: sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==} - file-entry-cache@10.0.8: - resolution: {integrity: sha512-FGXHpfmI4XyzbLd3HQ8cbUcsFGohJpZtmQRHr8z8FxxtCe2PcpgIlVLwIgunqjvRmXypBETvwhV4ptJizA+Y1Q==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@11.1.5: + resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==} file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} @@ -947,48 +1140,26 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - find-up@7.0.0: - resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} - engines: {node: '>=18'} - flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flat-cache@6.1.8: - resolution: {integrity: sha512-R6MaD3nrJAtO7C3QOuS79ficm2pEAy++TgEUD8ii1LVlbcgZ9DtASLkt9B+RZSFCzm7QHDMlXPsqqB6W2Pfr1Q==} - - flatted@3.3.2: - resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + flat-cache@6.1.23: + resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} flatted@3.3.3: resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - for-each@0.3.4: - resolution: {integrity: sha512-kKaIINnFpzW6ffJNDjjyjrk21BkDx38c0xa/klsT8VzLCaMEefv4ZTacrcVR4DmgTeBra++jMDAfS/tS799YDw==} - engines: {node: '>= 0.4'} + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} fraction.js@5.2.2: resolution: {integrity: sha512-uXBDv5knpYmv/2gLzWQ5mBHGBRk9wcKTeWu6GLTUEQfjCxO09uM/mHDrojlL+Q1mVGIIFo149Gba7od1XPgSzQ==} engines: {node: '>= 12'} - fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - - fuse.js@7.1.0: - resolution: {integrity: sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==} - engines: {node: '>=10'} + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} @@ -998,25 +1169,9 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.2.7: - resolution: {integrity: sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==} - engines: {node: '>= 0.4'} - - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stdin@9.0.0: - resolution: {integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==} - engines: {node: '>=12'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + engines: {node: '>=18'} glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -1038,72 +1193,49 @@ packages: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} engines: {node: '>=4'} - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + globals@17.11.0: + resolution: {integrity: sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==} engines: {node: '>=18'} - globals@16.0.0: - resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} + globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} engines: {node: '>=18'} - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - - globby@11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - - globby@14.0.2: - resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} - engines: {node: '>=18'} + globby@16.2.4: + resolution: {integrity: sha512-c8B/VNLmxRcmqqenRA9t+9IyOjf9+V6lTxPaUJLqOCONdQkWZ0ETYgX0qbtJqPsgCNusT9MZ5Jeidw8Eb9tn2g==} + engines: {node: '>=20'} globjoin@0.1.4: resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} + has-flag@5.0.1: + resolution: {integrity: sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==} + engines: {node: '>=12'} - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + hashery@1.5.1: + resolution: {integrity: sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==} + engines: {node: '>=20'} - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + hookified@1.15.1: + resolution: {integrity: sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==} - hookified@1.8.2: - resolution: {integrity: sha512-5nZbBNP44sFCDjSoB//0N7m508APCgbQ4mGGo1KJGBYyCKNHfry1Pvd0JVHZIxjdnqn8nFRBAN/eFB6Rk/4w5w==} + hookified@2.2.0: + resolution: {integrity: sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==} html-tags@3.3.1: resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} engines: {node: '>=8'} - ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + html-tags@5.1.0: + resolution: {integrity: sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==} + engines: {node: '>=20.10'} ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} @@ -1113,148 +1245,68 @@ packages: resolution: {integrity: sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==} engines: {node: '>= 4'} + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} + engines: {node: '>= 4'} + + import-cwd@3.0.0: + resolution: {integrity: sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==} + engines: {node: '>=8'} + import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} + import-from@3.0.0: + resolution: {integrity: sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==} + engines: {node: '>=8'} + + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} - inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - - is-core-module@2.16.1: - resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} - engines: {node: '>= 0.4'} - - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-function@1.1.0: - resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} - engines: {node: '>= 0.4'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} javascript-natural-sort@0.7.1: resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -1282,30 +1334,26 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true - jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - keyv@5.3.2: - resolution: {integrity: sha512-Lji2XRxqqa5Wg+CHLVfFKBImfJZ4pCSccu9eVWK6w4c2SDFLd8JAn1zqTuSFnsxb7ope6rMsnIHfp+eBbRBRZQ==} + keyv@5.6.0: + resolution: {integrity: sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==} kind-of@6.0.3: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - known-css-properties@0.35.0: - resolution: {integrity: sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==} + known-css-properties@0.37.0: + resolution: {integrity: sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==} language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -1321,60 +1369,57 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lint-to-the-future-eslint@3.3.0: + resolution: {integrity: sha512-tj/fRddJtlhz7/DWLoeK9ERxJ2OFK0Z6qWY74qu+IFYnIzz24Aal9EXuuUqdD+xT4Cl+pKSsddmoPDDXNMIw7Q==} + engines: {node: 10.* || >= 12.*} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + lint-to-the-future@2.6.4: + resolution: {integrity: sha512-aSLuYNNCLtkR7+Jlr4hBi6zPiSIldgdhFKfvhw/nS/7pglRYV0sEWoOkSRNPAc5aVSehPBsTQ21lVPZNZ5rjjQ==} + engines: {node: '>= 18'} + hasBin: true + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} lodash.kebabcase@4.1.1: resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} + engines: {node: 20 || >=22} + lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - mathjs@14.4.0: resolution: {integrity: sha512-CpoYDhNENefjIG9wU9epr+0pBHzlaySfpWcblZdAf5qXik/j/U8eSmx/oNbmXO0F5PyfwPGVD/wK4VWsTho1SA==} engines: {node: '>= 18'} hasBin: true - mathml-tag-names@2.1.3: - resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} + mathml-tag-names@4.0.0: + resolution: {integrity: sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==} mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} - mdn-data@2.21.0: - resolution: {integrity: sha512-+ZKPQezM5vYJIkCxaC+4DTnRrVZR1CgsKLu5zsQERQx6Tea8Y+wMx5A24rq8A8NepCeatIQufVAekKNgiBMsGQ==} + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} - meow@13.2.0: - resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} - engines: {node: '>=18'} + meow@14.1.0: + resolution: {integrity: sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==} + engines: {node: '>=20'} merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} @@ -1384,15 +1429,9 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} @@ -1400,8 +1439,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -1411,6 +1450,15 @@ packages: no-case@3.0.4: resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} @@ -1418,62 +1466,26 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + obug@2.1.4: + resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==} + engines: {node: '>=12.20.0'} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} - ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} + oxc-parser@0.130.0: + resolution: {integrity: sha512-X0PJ+NmOok8qP3vK9uaW431ngkdM9UPEK7KG466urtIL2+EYTEgbZK2yqe2MWKJKBjRlFweP/pJPx0x9muMEVw==} + engines: {node: ^20.19.0 || >=22.12.0} p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -1482,28 +1494,20 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - - path-type@4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - - path-type@5.0.0: - resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} - engines: {node: '>=12'} + path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -1512,9 +1516,9 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} postcss-media-query-parser@0.2.3: resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} @@ -1534,59 +1538,51 @@ packages: peerDependencies: postcss: ^8.4.29 - postcss-selector-parser@7.1.0: - resolution: {integrity: sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==} + postcss-selector-parser@7.1.5: + resolution: {integrity: sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==} engines: {node: '>=4'} postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + postcss@8.5.26: + resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-ember-template-tag@2.0.5: - resolution: {integrity: sha512-G9lbK3wmryIBSzqBKKoy254v7hIjqzqYpqWxi9NvOxcxNtwLyrC1u9NLJJFm+x9blzqHQOzKGOseVnbLtEwEbg==} + prettier-plugin-ember-template-tag@2.1.8: + resolution: {integrity: sha512-ioLdBFoZ11kuiuFF9/bGwHgzjiU3vQVOF1rQhcuEqGc1jmKBH+G3i3BL2yHGum2Z2IQOE/7MPstYo5iAU0Uhlw==} engines: {node: 18.* || >= 20} peerDependencies: prettier: '>= 3.0.0' - prettier@3.5.3: - resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + prettier@3.8.1: + resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} engines: {node: '>=14'} hasBin: true - proper-lockfile@4.1.2: - resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + qified@0.10.1: + resolution: {integrity: sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==} + engines: {node: '>=20'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} random-js@2.1.0: resolution: {integrity: sha512-CRUyWmnzmZBA7RZSVGq0xMqmgCyPPxbiKNLFA5ud7KenojVX2s7Gv+V7eB52beKTPGxWRnVZ7D/tCIgYJJ8vNQ==} - readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} - - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} + request-light@0.7.0: + resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==} require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} @@ -1608,19 +1604,6 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} - resolve@1.22.10: - resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} - engines: {node: '>= 0.4'} - hasBin: true - - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - - retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -1628,20 +1611,8 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} seedrandom@3.0.5: resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} @@ -1650,17 +1621,10 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} @@ -1670,36 +1634,20 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + shell-quote@1.9.0: + resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} engines: {node: '>= 0.4'} - signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + silent-error@1.1.1: + resolution: {integrity: sha512-n4iEKyNcg4v6/jpb3c0/iyH2G1nzUNl7Gpqtn/mHIJK9S/q/7MCfoO4rwVOoO59qPFIc0hVHvMbiOJ0NdtxKKw==} + simple-html-tokenizer@0.5.11: resolution: {integrity: sha512-C2WEK/Z3HoSFbYq8tI7ni3eOo/NneSPRoPpcM7WdLjFOArFuyXEjAoCdOC3DgMfRyziZQ1hCNR4mrNdWEvD0og==} - slash@3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - slash@5.1.0: resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} engines: {node: '>=14.16'} @@ -1719,99 +1667,76 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + string-width@8.2.2: + resolution: {integrity: sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==} + engines: {node: '>=20'} strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-bom@3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} - stylelint-config-recommended-scss@14.1.0: - resolution: {integrity: sha512-bhaMhh1u5dQqSsf6ri2GVWWQW5iUjBYgcHkh7SgDDn92ijoItC/cfO/W+fpXshgTQWhwFkP1rVcewcv4jaftRg==} - engines: {node: '>=18.12.0'} + stylelint-config-recommended-scss@17.0.1: + resolution: {integrity: sha512-x5DVehzJudcwF0od3sGpgkln2PLLranFE7twwbp7dqDINCyZvwzFkMc6TLhNOvazRiVBJYATQLouJY0xPGB8WA==} + engines: {node: '>=20'} peerDependencies: postcss: ^8.3.3 - stylelint: ^16.6.1 + stylelint: ^17.0.0 peerDependenciesMeta: postcss: optional: true - stylelint-config-recommended@14.0.1: - resolution: {integrity: sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==} - engines: {node: '>=18.12.0'} - peerDependencies: - stylelint: ^16.1.0 - - stylelint-config-recommended@15.0.0: - resolution: {integrity: sha512-9LejMFsat7L+NXttdHdTq94byn25TD+82bzGRiV1Pgasl99pWnwipXS5DguTpp3nP1XjvLXVnEJIuYBfsRjRkA==} - engines: {node: '>=18.12.0'} + stylelint-config-recommended@18.0.0: + resolution: {integrity: sha512-mxgT2XY6YZ3HWWe3Di8umG6aBmWmHTblTgu/f10rqFXnyWxjKWwNdjSWkgkwCtxIKnqjSJzvFmPT5yabVIRxZg==} + engines: {node: '>=20.19.0'} peerDependencies: - stylelint: ^16.13.0 + stylelint: ^17.0.0 - stylelint-config-standard-scss@14.0.0: - resolution: {integrity: sha512-6Pa26D9mHyi4LauJ83ls3ELqCglU6VfCXchovbEqQUiEkezvKdv6VgsIoMy58i00c854wVmOw0k8W5FTpuaVqg==} - engines: {node: '>=18.12.0'} + stylelint-config-standard-scss@17.0.0: + resolution: {integrity: sha512-uLJS6xgOCBw5EMsDW7Ukji8l28qRoMnkRch15s0qwZpskXvWt9oPzMmcYM307m9GN4MxuWLsQh4I6hU9yI53cQ==} + engines: {node: '>=20'} peerDependencies: postcss: ^8.3.3 - stylelint: ^16.11.0 + stylelint: ^17.0.0 peerDependenciesMeta: postcss: optional: true - stylelint-config-standard@36.0.1: - resolution: {integrity: sha512-8aX8mTzJ6cuO8mmD5yon61CWuIM4UD8Q5aBcWKGSf6kg+EC3uhB+iOywpTK4ca6ZL7B49en8yanOFtUW0qNzyw==} - engines: {node: '>=18.12.0'} + stylelint-config-standard@40.0.0: + resolution: {integrity: sha512-EznGJxOUhtWck2r6dJpbgAdPATIzvpLdK9+i5qPd4Lx70es66TkBPljSg4wN3Qnc6c4h2n+WbUrUynQ3fanjHw==} + engines: {node: '>=20.19.0'} peerDependencies: - stylelint: ^16.1.0 + stylelint: ^17.0.0 - stylelint-config-standard@37.0.0: - resolution: {integrity: sha512-+6eBlbSTrOn/il2RlV0zYGQwRTkr+WtzuVSs1reaWGObxnxLpbcspCUYajVQHonVfxVw2U+h42azGhrBvcg8OA==} - engines: {node: '>=18.12.0'} + stylelint-scss@7.2.0: + resolution: {integrity: sha512-6E79Bachv0Iz0gqRUZgdqdXCsiq26DWBWIBNHYtjTmAp3wJu6cp/I37VfW7BPntmh2puF3bY09XWl4HZGrLhzw==} + engines: {node: '>=20.19.0'} peerDependencies: - stylelint: ^16.13.0 + stylelint: ^16.8.2 || ^17.0.0 - stylelint-scss@6.11.1: - resolution: {integrity: sha512-e4rYo0UY+BIMtGeGanghrvHTjcryxgZbyFxUedp8dLFqC4P70aawNdYjRrQxbnKhu3BNr4+lt5e/53tcKXiwFA==} - engines: {node: '>=18.12.0'} - peerDependencies: - stylelint: ^16.0.2 - - stylelint@16.16.0: - resolution: {integrity: sha512-40X5UOb/0CEFnZVEHyN260HlSSUxPES+arrUphOumGWgXERHfwCD0kNBVILgQSij8iliYVwlc0V7M5bcLP9vPg==} - engines: {node: '>=18.12.0'} + stylelint@17.5.0: + resolution: {integrity: sha512-o/NS6zhsPZFmgUm5tXX4pVNg1XDOZSlucLdf2qow/lVn4JIyzZIQ5b3kad1ugqUj3GSIgr2u5lQw7X8rjqw33g==} + engines: {node: '>=20.19.0'} hasBin: true + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-hyperlinks@3.2.0: - resolution: {integrity: sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==} - engines: {node: '>=14.18'} + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} - supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} + supports-hyperlinks@4.5.0: + resolution: {integrity: sha512-ZW2OvfeCXrNTbLakPUzjQG922EeGCOteFSVoek5DKStTh898wf7zgtuFlzQN8HfZCxC3Eh02yJVrRW51hADf+w==} + engines: {node: '>=20'} svg-tags@1.0.0: resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} @@ -1820,19 +1745,35 @@ packages: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} + temporal-polyfill@0.2.5: + resolution: {integrity: sha512-ye47xp8Cb0nDguAhrrDS1JT1SzwEV9e26sSsrWzVu+yPZ7LzceEcH0i2gci9jWfOfSCCgM3Qv5nOYShVUUFUXA==} + + temporal-spec@0.2.4: + resolution: {integrity: sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ==} + tiny-emitter@2.1.0: resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} - tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -1841,46 +1782,43 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} typed-function@4.2.1: resolution: {integrity: sha512-EGjWssW7Tsk4DGfE+5yluuljS1OGYWiI1J6e8puZz9nTMM51Oug8CD5Zo4gWMsOhq5BI+1bF+rWTm4Vbj3ivRA==} engines: {node: '>= 18'} - typescript@5.8.3: - resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + typesafe-path@0.2.2: + resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} + + typescript-auto-import-cache@0.3.6: + resolution: {integrity: sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==} + + typescript-eslint@8.67.0: + resolution: {integrity: sha512-S2udFs8tCKEKffuJ4TB1idGUZiXdCPGi3IPBGWXarbLQ5UPXORV8QEVzJ4gCRduURMb5EkpNCdjbk0eDIuI8Yg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} - - unicorn-magic@0.1.0: - resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} - upath@2.0.1: - resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} - engines: {node: '>=4'} + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} update-browserslist-db@1.1.2: resolution: {integrity: sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==} @@ -1894,29 +1832,65 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - v8-compile-cache@2.4.0: - resolution: {integrity: sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw==} + volar-service-html@0.0.71: + resolution: {integrity: sha512-e8tHPhgQ7ooLfudAEIku+kgd9pWkq3SSz8RbnQDI1+Eb8wbenkLGHqoirLqz5ORLV6wIMr2Iv08RWBG5eOcgpw==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + volar-service-typescript@0.0.71: + resolution: {integrity: sha512-yTtM/BVT6hoyEYnDtaCyAtNhdNeS/mhTTABlBOdw3NNiRBUin3IznFJpgfjer4c6RYopiPjjQjc9VFhxVl1mLw==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} + vscode-html-languageservice@5.6.2: + resolution: {integrity: sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==} - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} + vscode-jsonrpc@9.0.1: + resolution: {integrity: sha512-rfuA6T75H6m5EkbhtEPzre9pT0HPcDI2MMy4+nPFIBks5J8JBAUHD4tRYSgaBOijIEC7SRkC1kKyXTLqbmh9jw==} + engines: {node: '>=14.0.0'} - which-typed-array@1.1.18: - resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} - engines: {node: '>= 0.4'} + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} - which@1.3.1: + vscode-languageserver-protocol@3.18.2: + resolution: {integrity: sha512-XRyDbT0Pp3sSNti3JmxVEUMySWCSi1hhM+/KUlCy1hV1zmrqpM1OwO12EAki8blhmLuIMpaJrYbo0OzGVfK2Qg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver-types@3.18.0: + resolution: {integrity: sha512-8TsGPNMIMiiBdkORgRSvLjuiEIiAFtO+KssmYWxQ+uSVvlf7RjK8YKCOjPzZ+YA04jXEV7+7LvkSmHkhpNS99g==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-nls@5.2.0: + resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==} + + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@1.3.1: resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} hasBin: true @@ -1929,16 +1903,13 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - workerpool@6.5.1: - resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + write-file-atomic@7.0.1: + resolution: {integrity: sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==} + engines: {node: ^20.17.0 || >=22.9.0} y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} @@ -1959,10 +1930,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.1.1: - resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==} - engines: {node: '>=12.20'} - snapshots: '@ampproject/remapping@2.3.0': @@ -1976,8 +1943,21 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/code-frame@8.0.0': + dependencies: + '@babel/helper-validator-identifier': 8.0.4 + js-tokens: 10.0.0 + '@babel/compat-data@7.26.5': {} + '@babel/compat-data@8.0.0': {} + '@babel/core@7.26.10': dependencies: '@ampproject/remapping': 2.3.0 @@ -1998,13 +1978,32 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/eslint-parser@7.27.0(@babel/core@7.26.10)(eslint@9.24.0)': + '@babel/core@8.0.1': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-compilation-targets': 8.0.0 + '@babel/helpers': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@types/gensync': 1.0.5 + convert-source-map: 2.0.0 + empathic: 2.0.1 + gensync: 1.0.0-beta.2 + import-meta-resolve: 4.2.0 + json5: 2.2.3 + obug: 2.1.4 + semver: 7.8.5 + + '@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0)': dependencies: - '@babel/core': 7.26.10 - '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 9.24.0 - eslint-visitor-keys: 2.1.0 - semver: 6.3.1 + '@babel/core': 8.0.1 + eslint: 10.6.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + semver: 7.8.5 '@babel/generator@7.27.0': dependencies: @@ -2014,9 +2013,30 @@ snapshots: '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 + '@babel/generator@7.29.8': + dependencies: + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/generator@8.0.0': + dependencies: + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + '@babel/helper-annotate-as-pure@7.25.9': dependencies: - '@babel/types': 7.26.7 + '@babel/types': 7.27.0 + + '@babel/helper-annotate-as-pure@8.0.0': + dependencies: + '@babel/types': 8.0.4 '@babel/helper-compilation-targets@7.26.5': dependencies: @@ -2026,18 +2046,13 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.26.10)': + '@babel/helper-compilation-targets@8.0.0': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.10) - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.26.7 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + '@babel/compat-data': 8.0.0 + '@babel/helper-validator-option': 8.0.0 + browserslist: 4.24.4 + lru-cache: 11.5.2 + semver: 7.8.5 '@babel/helper-create-class-features-plugin@7.27.0(@babel/core@7.26.10)': dependencies: @@ -2052,13 +2067,33 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-create-class-features-plugin@8.0.1(@babel/core@8.0.1)': + dependencies: + '@babel/core': 8.0.1 + '@babel/helper-annotate-as-pure': 8.0.0 + '@babel/helper-member-expression-to-functions': 8.0.0 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.1) + '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 + '@babel/traverse': 8.0.4 + semver: 7.8.5 + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-globals@8.0.0': {} + '@babel/helper-member-expression-to-functions@7.25.9': dependencies: '@babel/traverse': 7.27.0 - '@babel/types': 7.26.7 + '@babel/types': 7.27.0 transitivePeerDependencies: - supports-color + '@babel/helper-member-expression-to-functions@8.0.0': + dependencies: + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@babel/helper-module-imports@7.25.9': dependencies: '@babel/traverse': 7.27.0 @@ -2077,10 +2112,18 @@ snapshots: '@babel/helper-optimise-call-expression@7.25.9': dependencies: - '@babel/types': 7.26.7 + '@babel/types': 7.27.0 + + '@babel/helper-optimise-call-expression@8.0.0': + dependencies: + '@babel/types': 8.0.4 '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.1)': + dependencies: + '@babel/core': 8.0.1 + '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 @@ -2090,89 +2133,110 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.1)': + dependencies: + '@babel/core': 8.0.1 + '@babel/helper-member-expression-to-functions': 8.0.0 + '@babel/helper-optimise-call-expression': 8.0.0 + '@babel/traverse': 8.0.4 + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': dependencies: - '@babel/traverse': 7.26.7 - '@babel/types': 7.26.7 + '@babel/traverse': 7.27.0 + '@babel/types': 7.27.0 transitivePeerDependencies: - supports-color + '@babel/helper-skip-transparent-expression-wrappers@8.0.0': + dependencies: + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-string-parser@8.0.0': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-identifier@8.0.4': {} + '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-validator-option@8.0.0': {} + '@babel/helpers@7.27.0': dependencies: '@babel/template': 7.27.0 '@babel/types': 7.27.0 - '@babel/parser@7.26.7': + '@babel/helpers@8.0.0': dependencies: - '@babel/types': 7.26.7 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 '@babel/parser@7.27.0': dependencies: '@babel/types': 7.27.0 + '@babel/parser@7.29.8': + dependencies: + '@babel/types': 7.29.8 + + '@babel/parser@8.0.4': + dependencies: + '@babel/types': 8.0.4 + '@babel/plugin-proposal-decorators@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.10) + '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-decorators': 7.25.9(@babel/core@7.26.10) transitivePeerDependencies: - supports-color - '@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-proposal-decorators@8.0.2(@babel/core@8.0.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 + '@babel/core': 8.0.1 + '@babel/helper-create-class-features-plugin': 8.0.1(@babel/core@8.0.1) + '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.1) + '@babel/plugin-syntax-decorators': 8.0.1(@babel/core@8.0.1) - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.10)': + '@babel/plugin-syntax-decorators@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-transform-typescript@7.27.0(@babel/core@7.26.10)': + '@babel/plugin-syntax-decorators@8.0.1(@babel/core@8.0.1)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.27.0(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) - transitivePeerDependencies: - - supports-color + '@babel/core': 8.0.1 + '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.1) '@babel/runtime@7.27.0': dependencies: regenerator-runtime: 0.14.1 - '@babel/template@7.25.9': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.7 - '@babel/types': 7.26.7 - '@babel/template@7.27.0': dependencies: '@babel/code-frame': 7.26.2 '@babel/parser': 7.27.0 '@babel/types': 7.27.0 - '@babel/traverse@7.26.7': + '@babel/template@7.29.7': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.27.0 - '@babel/parser': 7.26.7 - '@babel/template': 7.25.9 - '@babel/types': 7.26.7 - debug: 4.4.0 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + + '@babel/template@8.0.0': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 '@babel/traverse@7.27.0': dependencies: @@ -2186,174 +2250,222 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.26.7': + '@babel/traverse@7.29.8': dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@8.0.4': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-globals': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 + obug: 2.1.4 '@babel/types@7.27.0': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@babel/types@8.0.4': + dependencies: + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.4 + + '@cacheable/memory@2.2.0': + dependencies: + '@cacheable/utils': 2.5.0 + '@keyv/bigmap': 1.3.1(keyv@5.6.0) + hookified: 1.15.1 + keyv: 5.6.0 + + '@cacheable/utils@2.5.0': dependencies: - '@csstools/css-tokenizer': 3.0.3 + hashery: 1.5.1 + keyv: 5.6.0 - '@csstools/css-tokenizer@3.0.3': {} + '@csstools/css-calc@3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.8(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 + + '@csstools/css-tokenizer@4.0.0': {} + + '@csstools/media-query-list-parser@5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 - '@csstools/media-query-list-parser@4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + '@csstools/selector-resolve-nested@4.0.1(postcss-selector-parser@7.1.5)': dependencies: - '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) - '@csstools/css-tokenizer': 3.0.3 + postcss-selector-parser: 7.1.5 - '@csstools/selector-specificity@5.0.0(postcss-selector-parser@7.1.0)': + '@csstools/selector-specificity@6.0.0(postcss-selector-parser@7.1.5)': dependencies: - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.5 '@dice-roller/rpg-dice-roller@5.5.1': dependencies: mathjs: 14.4.0 random-js: 2.1.0 - '@discourse/lint-configs@2.12.0(ember-template-lint@7.0.4(@babel/core@7.26.10))(eslint@9.24.0)(postcss@8.5.3)(prettier@3.5.3)(stylelint@16.16.0(typescript@5.8.3))': - dependencies: - '@babel/core': 7.26.10 - '@babel/eslint-parser': 7.27.0(@babel/core@7.26.10)(eslint@9.24.0) - '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.10) - ember-template-lint: 7.0.4(@babel/core@7.26.10) - eslint: 9.24.0 - eslint-plugin-decorator-position: 6.0.0(@babel/eslint-parser@7.27.0(@babel/core@7.26.10)(eslint@9.24.0))(eslint@9.24.0) - eslint-plugin-ember: 12.5.0(@babel/core@7.26.10)(eslint@9.24.0) - eslint-plugin-import: 2.31.0(eslint@9.24.0) - eslint-plugin-qunit: 8.1.2(eslint@9.24.0) - eslint-plugin-simple-import-sort: 12.1.1(eslint@9.24.0) - eslint-plugin-sort-class-members: 1.21.0(eslint@9.24.0) - globals: 16.0.0 - prettier: 3.5.3 - prettier-plugin-ember-template-tag: 2.0.5(prettier@3.5.3) - stylelint: 16.16.0(typescript@5.8.3) - stylelint-config-standard: 37.0.0(stylelint@16.16.0(typescript@5.8.3)) - stylelint-config-standard-scss: 14.0.0(postcss@8.5.3)(stylelint@16.16.0(typescript@5.8.3)) - typescript: 5.8.3 + '@discourse/lint-configs@3.2.0(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(eslint@10.6.0)(postcss@8.5.26)(prettier@3.8.1)(stylelint@17.5.0(typescript@5.9.3))': + dependencies: + '@babel/core': 8.0.1 + '@babel/eslint-parser': 8.0.1(@babel/core@8.0.1)(eslint@10.6.0) + '@babel/plugin-proposal-decorators': 8.0.2(@babel/core@8.0.1) + '@eslint/js': 10.0.1(eslint@10.6.0) + ember-eslint-parser: 0.14.6(@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0))(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(typescript@5.9.3) + eslint: 10.6.0 + eslint-plugin-decorator-position: 6.1.1(@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0))(eslint@10.6.0) + eslint-plugin-ember: 13.5.0(@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0))(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(eslint@10.6.0)(typescript@5.9.3) + eslint-plugin-qunit: 8.2.6(eslint@10.6.0) + eslint-plugin-simple-import-sort: 13.0.0(eslint@10.6.0) + eslint-plugin-sort-class-members: 1.22.1(eslint@10.6.0) + globals: 17.11.0 + prettier: 3.8.1 + prettier-plugin-ember-template-tag: 2.1.8(prettier@3.8.1) + stylelint: 17.5.0(typescript@5.9.3) + stylelint-config-standard: 40.0.0(stylelint@17.5.0(typescript@5.9.3)) + stylelint-config-standard-scss: 17.0.0(postcss@8.5.26)(stylelint@17.5.0(typescript@5.9.3)) + stylelint-scss: 7.2.0(stylelint@17.5.0(typescript@5.9.3)) + typescript: 5.9.3 + typescript-eslint: 8.67.0(eslint@10.6.0)(typescript@5.9.3) transitivePeerDependencies: - '@typescript-eslint/parser' - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - postcss - supports-color - '@dual-bundle/import-meta-resolve@4.1.0': {} + '@discourse/types@2026.3.0-d02b2966': {} '@ember-data/rfc395-data@0.0.4': {} - '@eslint-community/eslint-utils@4.4.1(eslint@9.24.0)': + '@emnapi/core@1.10.0': dependencies: - eslint: 9.24.0 - eslint-visitor-keys: 3.4.3 - - '@eslint-community/regexpp@4.12.1': {} + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true - '@eslint/config-array@0.20.0': + '@emnapi/runtime@1.10.0': dependencies: - '@eslint/object-schema': 2.1.6 - debug: 4.4.0 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + tslib: 2.8.1 + optional: true - '@eslint/config-helpers@0.2.1': {} + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true - '@eslint/core@0.12.0': + '@eslint-community/eslint-utils@4.10.1(eslint@10.6.0)': dependencies: - '@types/json-schema': 7.0.15 + eslint: 10.6.0 + eslint-visitor-keys: 3.4.3 - '@eslint/core@0.13.0': + '@eslint-community/eslint-utils@4.4.1(eslint@10.6.0)': dependencies: - '@types/json-schema': 7.0.15 + eslint: 10.6.0 + eslint-visitor-keys: 3.4.3 - '@eslint/eslintrc@3.3.1': + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.23.5': dependencies: - ajv: 6.12.6 + '@eslint/object-schema': 3.0.5 debug: 4.4.0 - espree: 10.3.0 - globals: 14.0.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 + minimatch: 10.2.6 transitivePeerDependencies: - supports-color - '@eslint/js@9.24.0': {} - - '@eslint/object-schema@2.1.6': {} - - '@eslint/plugin-kit@0.2.8': - dependencies: - '@eslint/core': 0.13.0 - levn: 0.4.1 - - '@glimmer/env@0.1.7': {} - - '@glimmer/global-context@0.84.3': + '@eslint/config-helpers@0.6.0': dependencies: - '@glimmer/env': 0.1.7 + '@eslint/core': 1.2.1 - '@glimmer/interfaces@0.84.3': + '@eslint/core@1.2.1': dependencies: - '@simple-dom/interface': 1.4.0 + '@types/json-schema': 7.0.15 - '@glimmer/interfaces@0.92.3': - dependencies: - '@simple-dom/interface': 1.4.0 + '@eslint/js@10.0.1(eslint@10.6.0)': + optionalDependencies: + eslint: 10.6.0 - '@glimmer/reference@0.84.3': - dependencies: - '@glimmer/env': 0.1.7 - '@glimmer/global-context': 0.84.3 - '@glimmer/interfaces': 0.84.3 - '@glimmer/util': 0.84.3 - '@glimmer/validator': 0.84.3 + '@eslint/object-schema@3.0.5': {} - '@glimmer/syntax@0.84.3': + '@eslint/plugin-kit@0.7.2': dependencies: - '@glimmer/interfaces': 0.84.3 - '@glimmer/util': 0.84.3 - '@handlebars/parser': 2.0.0 - simple-html-tokenizer: 0.5.11 + '@eslint/core': 1.2.1 + levn: 0.4.1 - '@glimmer/syntax@0.92.3': - dependencies: - '@glimmer/interfaces': 0.92.3 - '@glimmer/util': 0.92.3 - '@glimmer/wire-format': 0.92.3 - '@handlebars/parser': 2.0.0 - simple-html-tokenizer: 0.5.11 + '@glimmer/env@0.1.7': {} - '@glimmer/util@0.84.3': + '@glimmer/interfaces@0.94.6': dependencies: - '@glimmer/env': 0.1.7 - '@glimmer/interfaces': 0.84.3 '@simple-dom/interface': 1.4.0 + type-fest: 4.41.0 - '@glimmer/util@0.92.3': + '@glimmer/syntax@0.95.0': dependencies: - '@glimmer/env': 0.1.7 - '@glimmer/interfaces': 0.92.3 + '@glimmer/interfaces': 0.94.6 + '@glimmer/util': 0.94.8 + '@glimmer/wire-format': 0.94.8 + '@handlebars/parser': 2.2.2 + simple-html-tokenizer: 0.5.11 - '@glimmer/validator@0.84.3': - dependencies: - '@glimmer/env': 0.1.7 - '@glimmer/global-context': 0.84.3 + '@glimmer/util@0.94.8': + dependencies: + '@glimmer/interfaces': 0.94.6 + + '@glimmer/wire-format@0.94.8': + dependencies: + '@glimmer/interfaces': 0.94.6 + + '@glint/ember-tsc@1.8.11(typescript@5.9.3)': + dependencies: + '@glimmer/syntax': 0.95.0 + '@glint/template': 1.7.8 + '@volar/kit': 2.4.28(typescript@5.9.3) + '@volar/language-core': 2.4.28 + '@volar/language-server': 2.4.28 + '@volar/language-service': 2.4.28 + '@volar/source-map': 2.4.28 + '@volar/test-utils': 2.4.28 + '@volar/typescript': 2.4.28 + content-tag: 4.2.0 + silent-error: 1.1.1 + typescript: 5.9.3 + volar-service-html: 0.0.71(@volar/language-service@2.4.28) + volar-service-typescript: 0.0.71(@volar/language-service@2.4.28) + vscode-languageserver-protocol: 3.18.2 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + transitivePeerDependencies: + - supports-color - '@glimmer/wire-format@0.92.3': - dependencies: - '@glimmer/interfaces': 0.92.3 - '@glimmer/util': 0.92.3 + '@glint/template@1.7.8': {} - '@handlebars/parser@2.0.0': {} + '@handlebars/parser@2.2.2': {} '@humanfs/core@0.19.1': {} @@ -2368,6 +2480,11 @@ snapshots: '@humanwhocodes/retry@0.4.2': {} + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.31 + '@jridgewell/gen-mapping@0.3.8': dependencies: '@jridgewell/set-array': 1.2.1 @@ -2385,23 +2502,25 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@keyv/serialize@1.0.3': + '@jridgewell/trace-mapping@0.3.31': dependencies: - buffer: 6.0.3 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 - '@lint-todo/utils@13.1.1': + '@keyv/bigmap@1.3.1(keyv@5.6.0)': dependencies: - '@types/eslint': 8.56.12 - find-up: 5.0.0 - fs-extra: 9.1.0 - proper-lockfile: 4.1.2 - slash: 3.0.0 - tslib: 2.8.1 - upath: 2.0.1 + hashery: 1.5.1 + hookified: 1.15.1 + keyv: 5.6.0 - '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': + '@keyv/serialize@1.1.1': {} + + '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': dependencies: - eslint-scope: 5.1.1 + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.3 + optional: true '@nodelib/fs.scandir@2.1.5': dependencies: @@ -2415,193 +2534,297 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.0 - '@rtsao/scc@1.1.0': {} + '@one-ini/wasm@0.2.1': {} - '@simple-dom/interface@1.4.0': {} + '@oxc-parser/binding-android-arm-eabi@0.130.0': + optional: true - '@sindresorhus/merge-streams@2.3.0': {} + '@oxc-parser/binding-android-arm64@0.130.0': + optional: true - '@types/eslint@8.56.12': - dependencies: - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 + '@oxc-parser/binding-darwin-arm64@0.130.0': + optional: true - '@types/estree@1.0.6': {} + '@oxc-parser/binding-darwin-x64@0.130.0': + optional: true - '@types/json-schema@7.0.15': {} + '@oxc-parser/binding-freebsd-x64@0.130.0': + optional: true - '@types/json5@0.0.29': {} + '@oxc-parser/binding-linux-arm-gnueabihf@0.130.0': + optional: true - acorn-jsx@5.3.2(acorn@8.14.0): - dependencies: - acorn: 8.14.0 + '@oxc-parser/binding-linux-arm-musleabihf@0.130.0': + optional: true - acorn@8.14.0: {} + '@oxc-parser/binding-linux-arm64-gnu@0.130.0': + optional: true - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 + '@oxc-parser/binding-linux-arm64-musl@0.130.0': + optional: true - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 + '@oxc-parser/binding-linux-ppc64-gnu@0.130.0': + optional: true - ansi-regex@5.0.1: {} + '@oxc-parser/binding-linux-riscv64-gnu@0.130.0': + optional: true - ansi-styles@4.3.0: + '@oxc-parser/binding-linux-riscv64-musl@0.130.0': + optional: true + + '@oxc-parser/binding-linux-s390x-gnu@0.130.0': + optional: true + + '@oxc-parser/binding-linux-x64-gnu@0.130.0': + optional: true + + '@oxc-parser/binding-linux-x64-musl@0.130.0': + optional: true + + '@oxc-parser/binding-openharmony-arm64@0.130.0': + optional: true + + '@oxc-parser/binding-wasm32-wasi@0.130.0': dependencies: - color-convert: 2.0.1 + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true - argparse@2.0.1: {} + '@oxc-parser/binding-win32-arm64-msvc@0.130.0': + optional: true - aria-query@5.3.2: {} + '@oxc-parser/binding-win32-ia32-msvc@0.130.0': + optional: true - array-buffer-byte-length@1.0.2: + '@oxc-parser/binding-win32-x64-msvc@0.130.0': + optional: true + + '@oxc-project/types@0.130.0': {} + + '@simple-dom/interface@1.4.0': {} + + '@sindresorhus/merge-streams@2.3.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@tybys/wasm-util@0.10.3': dependencies: - call-bound: 1.0.3 - is-array-buffer: 3.0.5 + tslib: 2.8.1 + optional: true - array-includes@3.1.8: + '@types/esrecurse@4.3.1': {} + + '@types/estree@1.0.6': {} + + '@types/estree@1.0.9': {} + + '@types/gensync@1.0.5': {} + + '@types/jsesc@2.5.1': {} + + '@types/json-schema@7.0.15': {} + + '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(eslint@10.6.0)(typescript@5.9.3)': dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-object-atoms: 1.1.1 - get-intrinsic: 1.2.7 - is-string: 1.1.1 + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.67.0(eslint@10.6.0)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/type-utils': 8.67.0(eslint@10.6.0)(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.6.0)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 + eslint: 10.6.0 + ignore: 7.0.6 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color - array-union@2.1.0: {} + '@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 + debug: 4.4.3 + eslint: 10.6.0 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color - array.prototype.findlastindex@1.2.6: + '@typescript-eslint/project-service@8.67.0(typescript@5.9.3)': dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color - array.prototype.flat@1.3.3: + '@typescript-eslint/scope-manager@8.67.0': dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-shim-unscopables: 1.1.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 - array.prototype.flatmap@1.3.3: + '@typescript-eslint/tsconfig-utils@8.67.0(typescript@5.9.3)': dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-shim-unscopables: 1.1.0 + typescript: 5.9.3 - arraybuffer.prototype.slice@1.0.4: + '@typescript-eslint/type-utils@8.67.0(eslint@10.6.0)(typescript@5.9.3)': dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 - is-array-buffer: 3.0.5 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.6.0)(typescript@5.9.3) + debug: 4.4.3 + eslint: 10.6.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color - astral-regex@2.0.0: {} + '@typescript-eslint/types@8.67.0': {} - async-function@1.0.0: {} + '@typescript-eslint/typescript-estree@8.67.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.67.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 + debug: 4.4.3 + minimatch: 10.2.6 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color - async-promise-queue@1.0.5: + '@typescript-eslint/utils@8.67.0(eslint@10.6.0)(typescript@5.9.3)': dependencies: - async: 2.6.4 - debug: 2.6.9 + '@eslint-community/eslint-utils': 4.10.1(eslint@10.6.0) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + eslint: 10.6.0 + typescript: 5.9.3 transitivePeerDependencies: - supports-color - async@2.6.4: + '@typescript-eslint/visitor-keys@8.67.0': dependencies: - lodash: 4.17.21 + '@typescript-eslint/types': 8.67.0 + eslint-visitor-keys: 5.0.1 - at-least-node@1.0.0: {} + '@volar/kit@2.4.28(typescript@5.9.3)': + dependencies: + '@volar/language-service': 2.4.28 + '@volar/typescript': 2.4.28 + typesafe-path: 0.2.2 + typescript: 5.9.3 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 - available-typed-arrays@1.0.7: + '@volar/language-core@2.4.28': dependencies: - possible-typed-array-names: 1.0.0 + '@volar/source-map': 2.4.28 - balanced-match@1.0.2: {} + '@volar/language-server@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + '@volar/language-service': 2.4.28 + '@volar/typescript': 2.4.28 + path-browserify: 1.0.1 + request-light: 0.7.0 + vscode-languageserver: 9.0.1 + vscode-languageserver-protocol: 3.18.2 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 - balanced-match@2.0.0: {} + '@volar/language-service@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + vscode-languageserver-protocol: 3.18.2 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 - base64-js@1.5.1: {} + '@volar/source-map@2.4.28': {} - bl@4.1.0: + '@volar/test-utils@2.4.28': dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 + '@volar/language-core': 2.4.28 + '@volar/language-server': 2.4.28 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 - brace-expansion@1.1.11: + '@volar/typescript@2.4.28': dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 + '@volar/language-core': 2.4.28 + path-browserify: 1.0.1 + vscode-uri: 3.1.0 - braces@3.0.3: - dependencies: - fill-range: 7.1.1 + '@vscode/l10n@0.0.18': {} - browserslist@4.24.4: + acorn-jsx@5.3.2(acorn@8.18.0): dependencies: - caniuse-lite: 1.0.30001697 - electron-to-chromium: 1.5.93 - node-releases: 2.0.19 - update-browserslist-db: 1.1.2(browserslist@4.24.4) + acorn: 8.18.0 - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 + acorn@8.18.0: {} - buffer@6.0.3: + ajv@6.15.0: dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 - cacheable@1.8.10: + ajv@8.17.1: dependencies: - hookified: 1.8.2 - keyv: 5.3.2 + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 - call-bind-apply-helpers@1.0.1: + ansi-regex@5.0.1: {} + + ansi-regex@6.3.0: {} + + ansi-styles@4.3.0: dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + astral-regex@2.0.0: {} - call-bind-apply-helpers@1.0.2: + axobject-query@4.1.0: {} + + balanced-match@4.0.4: {} + + brace-expansion@5.0.9: dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 + balanced-match: 4.0.4 - call-bind@1.0.8: + braces@3.0.3: dependencies: - call-bind-apply-helpers: 1.0.1 - es-define-property: 1.0.1 - get-intrinsic: 1.2.7 - set-function-length: 1.2.2 + fill-range: 7.1.1 - call-bound@1.0.3: + browserslist@4.24.4: dependencies: - call-bind-apply-helpers: 1.0.1 - get-intrinsic: 1.2.7 + caniuse-lite: 1.0.30001697 + electron-to-chromium: 1.5.93 + node-releases: 2.0.19 + update-browserslist-db: 1.1.2(browserslist@4.24.4) - call-bound@1.0.4: + cacheable@2.5.0: dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 + '@cacheable/memory': 2.2.0 + '@cacheable/utils': 2.5.0 + hookified: 1.15.1 + keyv: 5.6.0 + qified: 0.10.1 callsites@3.1.0: {} @@ -2612,24 +2835,12 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.4.1: {} - - ci-info@4.1.0: {} - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.9.2: {} - cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - clone@1.0.4: {} - color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -2638,32 +2849,33 @@ snapshots: colord@2.9.3: {} - colors@1.4.0: {} + commander@14.0.3: {} - commander@8.3.0: {} + commander@9.5.0: {} complex.js@2.4.2: {} - concat-map@0.0.1: {} - - content-tag-utils@0.3.1: + concurrently@9.2.4: dependencies: - content-tag: 3.1.2 - - content-tag@2.0.3: {} + chalk: 4.1.2 + rxjs: 7.8.2 + shell-quote: 1.9.0 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 - content-tag@3.1.2: {} + content-tag@4.2.0: {} convert-source-map@2.0.0: {} - cosmiconfig@9.0.0(typescript@5.8.3): + cosmiconfig@9.0.2(typescript@5.9.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.8.3 + typescript: 5.9.3 cross-spawn@7.0.6: dependencies: @@ -2671,44 +2883,29 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-functions-list@3.2.3: {} + css-functions-list@3.3.3: {} css-tree@3.1.0: dependencies: mdn-data: 2.12.2 source-map-js: 1.2.1 - cssesc@3.0.0: {} - - data-view-buffer@1.0.2: + css-tree@3.2.1: dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-data-view: 1.0.2 + mdn-data: 2.27.1 + source-map-js: 1.2.1 - date-fns@3.6.0: {} + cssesc@3.0.0: {} debug@2.6.9: dependencies: ms: 2.0.0 - debug@3.2.7: + debug@4.4.0: dependencies: ms: 2.1.3 - debug@4.4.0: + debug@4.4.3: dependencies: ms: 2.1.3 @@ -2716,337 +2913,152 @@ snapshots: deep-is@0.1.4: {} - defaults@1.0.4: - dependencies: - clone: 1.0.4 - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - dot-case@3.0.4: dependencies: no-case: 3.0.4 tslib: 2.8.1 - dunder-proto@1.0.1: + editorconfig@3.0.2: dependencies: - call-bind-apply-helpers: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 + '@one-ini/wasm': 0.2.1 + commander: 14.0.3 + minimatch: 10.2.6 + semver: 7.8.5 electron-to-chromium@1.5.93: {} - ember-eslint-parser@0.5.9(@babel/core@7.26.10)(eslint@9.24.0): + ember-eslint-parser@0.14.6(@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0))(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@babel/core': 7.26.10 - '@babel/eslint-parser': 7.27.0(@babel/core@7.26.10)(eslint@9.24.0) - '@glimmer/syntax': 0.92.3 - content-tag: 2.0.3 - eslint-scope: 7.2.2 - html-tags: 3.3.1 - mathml-tag-names: 2.1.3 + '@glimmer/syntax': 0.95.0 + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + content-tag: 4.2.0 + ember-estree: 0.6.11 + eslint-scope: 9.1.2 + html-tags: 5.1.0 + mathml-tag-names: 4.0.0 svg-tags: 1.0.0 + optionalDependencies: + '@babel/eslint-parser': 8.0.1(@babel/core@8.0.1)(eslint@10.6.0) + '@typescript-eslint/parser': 8.67.0(eslint@10.6.0)(typescript@5.9.3) transitivePeerDependencies: - - eslint - - ember-rfc176-data@0.3.18: {} + - typescript - ember-template-lint@7.0.4(@babel/core@7.26.10): + ember-estree@0.6.11: dependencies: - '@babel/generator': 7.27.0 - '@babel/parser': 7.26.7 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-typescript': 7.27.0(@babel/core@7.26.10) - '@babel/traverse': 7.26.7 - '@lint-todo/utils': 13.1.1 - aria-query: 5.3.2 - chalk: 5.4.1 - ci-info: 4.1.0 - content-tag: 3.1.2 - content-tag-utils: 0.3.1 - date-fns: 3.6.0 - ember-template-recast: 6.1.5 - eslint-formatter-kakoune: 1.0.0 - find-up: 7.0.0 - fuse.js: 7.1.0 - get-stdin: 9.0.0 - globby: 14.0.2 - is-glob: 4.0.3 - language-tags: 1.0.9 - micromatch: 4.0.8 - resolve: 1.22.10 - v8-compile-cache: 2.4.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@babel/core' - - supports-color + '@glimmer/env': 0.1.7 + '@glimmer/syntax': 0.95.0 + content-tag: 4.2.0 + oxc-parser: 0.130.0 - ember-template-recast@6.1.5: - dependencies: - '@glimmer/reference': 0.84.3 - '@glimmer/syntax': 0.84.3 - '@glimmer/validator': 0.84.3 - async-promise-queue: 1.0.5 - colors: 1.4.0 - commander: 8.3.0 - globby: 11.1.0 - ora: 5.4.1 - slash: 3.0.0 - tmp: 0.2.3 - workerpool: 6.5.1 - transitivePeerDependencies: - - supports-color + ember-rfc176-data@0.3.18: {} emoji-regex@8.0.0: {} + empathic@2.0.1: {} + env-paths@2.2.1: {} error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 - es-abstract@1.23.9: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.3 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.2.7 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-regex: 1.2.1 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.18 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.2.7 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - escalade@3.2.0: {} - escape-latex@1.2.0: {} - - escape-string-regexp@4.0.0: {} - - eslint-formatter-kakoune@1.0.0: {} - - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.24.0): - dependencies: - debug: 3.2.7 - optionalDependencies: - eslint: 9.24.0 - eslint-import-resolver-node: 0.3.9 - transitivePeerDependencies: - - supports-color + escape-latex@1.2.0: {} + + escape-string-regexp@4.0.0: {} - eslint-plugin-decorator-position@6.0.0(@babel/eslint-parser@7.27.0(@babel/core@7.26.10)(eslint@9.24.0))(eslint@9.24.0): + eslint-plugin-decorator-position@6.1.1(@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0))(eslint@10.6.0): dependencies: '@babel/core': 7.26.10 '@babel/plugin-proposal-decorators': 7.25.9(@babel/core@7.26.10) '@ember-data/rfc395-data': 0.0.4 ember-rfc176-data: 0.3.18 - eslint: 9.24.0 + eslint: 10.6.0 snake-case: 3.0.4 optionalDependencies: - '@babel/eslint-parser': 7.27.0(@babel/core@7.26.10)(eslint@9.24.0) + '@babel/eslint-parser': 8.0.1(@babel/core@8.0.1)(eslint@10.6.0) transitivePeerDependencies: - supports-color - eslint-plugin-ember@12.5.0(@babel/core@7.26.10)(eslint@9.24.0): + eslint-plugin-ember@13.5.0(@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0))(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(eslint@10.6.0)(typescript@5.9.3): dependencies: '@ember-data/rfc395-data': 0.0.4 + aria-query: 5.3.2 + axobject-query: 4.1.0 css-tree: 3.1.0 - ember-eslint-parser: 0.5.9(@babel/core@7.26.10)(eslint@9.24.0) + editorconfig: 3.0.2 + ember-eslint-parser: 0.14.6(@babel/eslint-parser@8.0.1(@babel/core@8.0.1)(eslint@10.6.0))(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(typescript@5.9.3) ember-rfc176-data: 0.3.18 - eslint: 9.24.0 - eslint-utils: 3.0.0(eslint@9.24.0) + eslint: 10.6.0 + eslint-utils: 3.0.0(eslint@10.6.0) estraverse: 5.3.0 + html-tags: 3.3.1 + language-tags: 1.0.9 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 + mathml-tag-names: 4.0.0 requireindex: 1.2.0 snake-case: 3.0.4 + svg-tags: 1.0.0 + optionalDependencies: + '@typescript-eslint/parser': 8.67.0(eslint@10.6.0)(typescript@5.9.3) transitivePeerDependencies: - - '@babel/core' - - eslint-plugin-import@2.31.0(eslint@9.24.0): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.8 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.24.0 - eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(eslint-import-resolver-node@0.3.9)(eslint@9.24.0) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color + - '@babel/eslint-parser' + - typescript - eslint-plugin-qunit@8.1.2(eslint@9.24.0): + eslint-plugin-qunit@8.2.6(eslint@10.6.0): dependencies: - eslint-utils: 3.0.0(eslint@9.24.0) + '@eslint-community/eslint-utils': 4.4.1(eslint@10.6.0) + eslint: 10.6.0 requireindex: 1.2.0 - transitivePeerDependencies: - - eslint - - eslint-plugin-simple-import-sort@12.1.1(eslint@9.24.0): - dependencies: - eslint: 9.24.0 - eslint-plugin-sort-class-members@1.21.0(eslint@9.24.0): + eslint-plugin-simple-import-sort@13.0.0(eslint@10.6.0): dependencies: - eslint: 9.24.0 + eslint: 10.6.0 - eslint-scope@5.1.1: + eslint-plugin-sort-class-members@1.22.1(eslint@10.6.0): dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 + eslint: 10.6.0 - eslint-scope@8.3.0: + eslint-scope@9.1.2: dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.9 esrecurse: 4.3.0 estraverse: 5.3.0 - eslint-utils@3.0.0(eslint@9.24.0): + eslint-utils@3.0.0(eslint@10.6.0): dependencies: - eslint: 9.24.0 + eslint: 10.6.0 eslint-visitor-keys: 2.1.0 eslint-visitor-keys@2.1.0: {} eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@5.0.1: {} - eslint@9.24.0: + eslint@10.6.0: dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.24.0) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.20.0 - '@eslint/config-helpers': 0.2.1 - '@eslint/core': 0.12.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.24.0 - '@eslint/plugin-kit': 0.2.8 + '@eslint-community/eslint-utils': 4.10.1(eslint@10.6.0) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.6.0 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.2 '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 + ajv: 6.15.0 cross-spawn: 7.0.6 debug: 4.4.0 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 - esquery: 1.6.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 8.0.0 @@ -3056,20 +3068,19 @@ snapshots: imurmurhash: 0.1.4 is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 10.2.6 natural-compare: 1.4.0 optionator: 0.9.4 transitivePeerDependencies: - supports-color - espree@10.3.0: + espree@11.2.0: dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 4.2.0 + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) + eslint-visitor-keys: 5.0.1 - esquery@1.6.0: + esquery@1.7.0: dependencies: estraverse: 5.3.0 @@ -3077,8 +3088,6 @@ snapshots: dependencies: estraverse: 5.3.0 - estraverse@4.3.0: {} - estraverse@5.3.0: {} esutils@2.0.3: {} @@ -3105,9 +3114,13 @@ snapshots: dependencies: reusify: 1.0.4 - file-entry-cache@10.0.8: + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + file-entry-cache@11.1.5: dependencies: - flat-cache: 6.1.8 + flat-cache: 6.1.23 file-entry-cache@8.0.0: dependencies: @@ -3122,97 +3135,34 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - find-up@7.0.0: - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - unicorn-magic: 0.1.0 - flat-cache@4.0.1: dependencies: - flatted: 3.3.2 + flatted: 3.3.3 keyv: 4.5.4 - flat-cache@6.1.8: + flat-cache@6.1.23: dependencies: - cacheable: 1.8.10 - flatted: 3.3.3 - hookified: 1.8.2 - - flatted@3.3.2: {} + cacheable: 2.5.0 + flatted: 3.4.4 + hookified: 1.15.1 flatted@3.3.3: {} - for-each@0.3.4: - dependencies: - is-callable: 1.2.7 + flatted@3.4.4: {} fraction.js@5.2.2: {} - fs-extra@9.1.0: + fs-extra@7.0.1: dependencies: - at-least-node: 1.0.0 graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - - fuse.js@7.1.0: {} + jsonfile: 4.0.0 + universalify: 0.1.2 gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} - get-intrinsic@1.2.7: - dependencies: - call-bind-apply-helpers: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stdin@9.0.0: {} - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 + get-east-asian-width@1.6.0: {} glob-parent@5.1.2: dependencies: @@ -3234,209 +3184,94 @@ snapshots: globals@11.12.0: {} - globals@14.0.0: {} - - globals@16.0.0: {} - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 + globals@17.11.0: {} - globby@11.1.0: + globby@14.1.0: dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 + '@sindresorhus/merge-streams': 2.3.0 fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 + ignore: 7.0.3 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 - globby@14.0.2: + globby@16.2.4: dependencies: - '@sindresorhus/merge-streams': 2.3.0 + '@sindresorhus/merge-streams': 4.0.0 fast-glob: 3.3.3 - ignore: 5.3.2 - path-type: 5.0.0 + ignore: 7.0.6 + is-path-inside: 4.0.0 + micromatch: 4.0.8 slash: 5.1.0 - unicorn-magic: 0.1.0 + unicorn-magic: 0.4.0 globjoin@0.1.4: {} - gopd@1.2.0: {} - graceful-fs@4.2.11: {} - has-bigints@1.1.0: {} - has-flag@4.0.0: {} - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.1.0: {} + has-flag@5.0.1: {} - has-tostringtag@1.0.2: + hashery@1.5.1: dependencies: - has-symbols: 1.1.0 + hookified: 1.15.1 - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 + hookified@1.15.1: {} - hookified@1.8.2: {} + hookified@2.2.0: {} html-tags@3.3.1: {} - ieee754@1.2.1: {} + html-tags@5.1.0: {} ignore@5.3.2: {} ignore@7.0.3: {} - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - imurmurhash@0.1.4: {} - - inherits@2.0.4: {} - - ini@1.3.8: {} - - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - get-intrinsic: 1.2.7 - - is-arrayish@0.2.1: {} + ignore@7.0.6: {} - is-async-function@2.1.1: + import-cwd@3.0.0: dependencies: - async-function: 1.0.0 - call-bound: 1.0.3 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 + import-from: 3.0.0 - is-bigint@1.1.0: + import-fresh@3.3.1: dependencies: - has-bigints: 1.1.0 + parent-module: 1.0.1 + resolve-from: 4.0.0 - is-boolean-object@1.2.2: + import-from@3.0.0: dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 + resolve-from: 5.0.0 - is-callable@1.2.7: {} + import-meta-resolve@4.2.0: {} - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 + imurmurhash@0.1.4: {} - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.3 - get-intrinsic: 1.2.7 - is-typed-array: 1.1.15 + ini@1.3.8: {} - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 + is-arrayish@0.2.1: {} is-extglob@2.1.1: {} - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.3 - is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.1.0: - dependencies: - call-bound: 1.0.3 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - is-interactive@1.0.0: {} - - is-map@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 - is-number@7.0.0: {} - is-plain-object@5.0.0: {} - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.3 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.3 - - is-string@1.1.1: - dependencies: - call-bound: 1.0.3 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.3 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.18 - - is-unicode-supported@0.1.0: {} - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.3 + is-path-inside@4.0.0: {} - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.3 - get-intrinsic: 1.2.7 - - isarray@2.0.5: {} + is-plain-object@5.0.0: {} isexe@2.0.0: {} javascript-natural-sort@0.7.1: {} + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-yaml@4.1.0: @@ -3455,15 +3290,9 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json5@1.0.2: - dependencies: - minimist: 1.2.8 - json5@2.2.3: {} - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 @@ -3471,13 +3300,13 @@ snapshots: dependencies: json-buffer: 3.0.1 - keyv@5.3.2: + keyv@5.6.0: dependencies: - '@keyv/serialize': 1.0.3 + '@keyv/serialize': 1.1.1 kind-of@6.0.3: {} - known-css-properties@0.35.0: {} + known-css-properties@0.37.0: {} language-subtag-registry@0.3.23: {} @@ -3492,39 +3321,42 @@ snapshots: lines-and-columns@1.2.4: {} - locate-path@6.0.0: + lint-to-the-future-eslint@3.3.0(eslint@10.6.0): dependencies: - p-locate: 5.0.0 + eslint: 10.6.0 + globby: 14.1.0 + import-cwd: 3.0.0 + + lint-to-the-future@2.6.4: + dependencies: + commander: 9.5.0 + fs-extra: 7.0.1 + import-cwd: 3.0.0 + node-fetch: 2.7.0 + temporal-polyfill: 0.2.5 + transitivePeerDependencies: + - encoding - locate-path@7.2.0: + locate-path@6.0.0: dependencies: - p-locate: 6.0.0 + p-locate: 5.0.0 lodash.camelcase@4.3.0: {} lodash.kebabcase@4.1.1: {} - lodash.merge@4.6.2: {} - lodash.truncate@4.4.2: {} - lodash@4.17.21: {} - - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - lower-case@2.0.2: dependencies: tslib: 2.8.1 + lru-cache@11.5.2: {} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 - math-intrinsics@1.1.0: {} - mathjs@14.4.0: dependencies: '@babel/runtime': 7.27.0 @@ -3537,13 +3369,13 @@ snapshots: tiny-emitter: 2.1.0 typed-function: 4.2.1 - mathml-tag-names@2.1.3: {} + mathml-tag-names@4.0.0: {} mdn-data@2.12.2: {} - mdn-data@2.21.0: {} + mdn-data@2.27.1: {} - meow@13.2.0: {} + meow@14.1.0: {} merge2@1.4.1: {} @@ -3552,19 +3384,15 @@ snapshots: braces: 3.0.3 picomatch: 2.3.1 - mimic-fn@2.1.0: {} - - minimatch@3.1.2: + minimatch@10.2.6: dependencies: - brace-expansion: 1.1.11 - - minimist@1.2.8: {} + brace-expansion: 5.0.9 ms@2.0.0: {} ms@2.1.3: {} - nanoid@3.3.11: {} + nanoid@3.3.18: {} natural-compare@1.4.0: {} @@ -3573,46 +3401,15 @@ snapshots: lower-case: 2.0.2 tslib: 2.8.1 - node-releases@2.0.19: {} - - normalize-path@3.0.0: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.fromentries@2.0.8: + node-fetch@2.7.0: dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-object-atoms: 1.1.1 + whatwg-url: 5.0.0 - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 + node-releases@2.0.19: {} - object.values@1.2.1: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 + normalize-path@3.0.0: {} - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 + obug@2.1.4: {} optionator@0.9.4: dependencies: @@ -3623,40 +3420,39 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 - ora@5.4.1: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - - own-keys@1.0.1: + oxc-parser@0.130.0: dependencies: - get-intrinsic: 1.2.7 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 + '@oxc-project/types': 0.130.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.130.0 + '@oxc-parser/binding-android-arm64': 0.130.0 + '@oxc-parser/binding-darwin-arm64': 0.130.0 + '@oxc-parser/binding-darwin-x64': 0.130.0 + '@oxc-parser/binding-freebsd-x64': 0.130.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.130.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.130.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.130.0 + '@oxc-parser/binding-linux-arm64-musl': 0.130.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.130.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.130.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.130.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.130.0 + '@oxc-parser/binding-linux-x64-gnu': 0.130.0 + '@oxc-parser/binding-linux-x64-musl': 0.130.0 + '@oxc-parser/binding-openharmony-arm64': 0.130.0 + '@oxc-parser/binding-wasm32-wasi': 0.130.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.130.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.130.0 + '@oxc-parser/binding-win32-x64-msvc': 0.130.0 p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - p-limit@4.0.0: - dependencies: - yocto-queue: 1.1.1 - p-locate@5.0.0: dependencies: p-limit: 3.1.0 - p-locate@6.0.0: - dependencies: - p-limit: 4.0.0 - parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -3668,100 +3464,70 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - path-exists@4.0.0: {} + path-browserify@1.0.1: {} - path-exists@5.0.0: {} + path-exists@4.0.0: {} path-key@3.1.1: {} - path-parse@1.0.7: {} - - path-type@4.0.0: {} - - path-type@5.0.0: {} + path-type@6.0.0: {} picocolors@1.1.1: {} picomatch@2.3.1: {} - possible-typed-array-names@1.0.0: {} + picomatch@4.0.5: {} postcss-media-query-parser@0.2.3: {} postcss-resolve-nested-selector@0.1.6: {} - postcss-safe-parser@7.0.1(postcss@8.5.3): + postcss-safe-parser@7.0.1(postcss@8.5.26): dependencies: - postcss: 8.5.3 + postcss: 8.5.26 - postcss-scss@4.0.9(postcss@8.5.3): + postcss-scss@4.0.9(postcss@8.5.26): dependencies: - postcss: 8.5.3 + postcss: 8.5.26 - postcss-selector-parser@7.1.0: + postcss-selector-parser@7.1.5: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 postcss-value-parser@4.2.0: {} - postcss@8.5.3: + postcss@8.5.26: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.18 picocolors: 1.1.1 source-map-js: 1.2.1 prelude-ls@1.2.1: {} - prettier-plugin-ember-template-tag@2.0.5(prettier@3.5.3): + prettier-plugin-ember-template-tag@2.1.8(prettier@3.8.1): dependencies: - '@babel/core': 7.26.10 - content-tag: 3.1.2 - prettier: 3.5.3 + '@babel/traverse': 7.29.8 + content-tag: 4.2.0 + prettier: 3.8.1 transitivePeerDependencies: - supports-color - prettier@3.5.3: {} - - proper-lockfile@4.1.2: - dependencies: - graceful-fs: 4.2.11 - retry: 0.12.0 - signal-exit: 3.0.7 + prettier@3.8.1: {} punycode@2.3.1: {} + qified@0.10.1: + dependencies: + hookified: 2.2.0 + queue-microtask@1.2.3: {} random-js@2.1.0: {} - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.2.7 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - regenerator-runtime@0.14.1: {} - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 + request-light@0.7.0: {} require-directory@2.1.1: {} @@ -3773,71 +3539,21 @@ snapshots: resolve-from@5.0.0: {} - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - - retry@0.12.0: {} - reusify@1.0.4: {} run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - get-intrinsic: 1.2.7 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-buffer@5.2.1: {} - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: + rxjs@7.8.2: dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-regex: 1.2.1 + tslib: 2.8.1 seedrandom@3.0.5: {} semver@6.3.1: {} - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.7 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 + semver@7.8.5: {} shebang-command@2.0.0: dependencies: @@ -3845,42 +3561,18 @@ snapshots: shebang-regex@3.0.0: {} - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 - object-inspect: 1.13.4 + shell-quote@1.9.0: {} - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - get-intrinsic: 1.2.7 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 + signal-exit@4.1.0: {} - side-channel@1.1.0: + silent-error@1.1.1: dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} + debug: 2.6.9 + transitivePeerDependencies: + - supports-color simple-html-tokenizer@0.5.11: {} - slash@3.0.0: {} - slash@5.1.0: {} slice-ansi@4.0.0: @@ -3902,142 +3594,117 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.23.9 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.3 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string_decoder@1.3.0: + string-width@8.2.2: dependencies: - safe-buffer: 5.2.1 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - strip-bom@3.0.0: {} - - strip-json-comments@3.1.1: {} - - stylelint-config-recommended-scss@14.1.0(postcss@8.5.3)(stylelint@16.16.0(typescript@5.8.3)): + strip-ansi@7.2.0: dependencies: - postcss-scss: 4.0.9(postcss@8.5.3) - stylelint: 16.16.0(typescript@5.8.3) - stylelint-config-recommended: 14.0.1(stylelint@16.16.0(typescript@5.8.3)) - stylelint-scss: 6.11.1(stylelint@16.16.0(typescript@5.8.3)) - optionalDependencies: - postcss: 8.5.3 + ansi-regex: 6.3.0 - stylelint-config-recommended@14.0.1(stylelint@16.16.0(typescript@5.8.3)): + stylelint-config-recommended-scss@17.0.1(postcss@8.5.26)(stylelint@17.5.0(typescript@5.9.3)): dependencies: - stylelint: 16.16.0(typescript@5.8.3) + postcss-scss: 4.0.9(postcss@8.5.26) + stylelint: 17.5.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.5.0(typescript@5.9.3)) + stylelint-scss: 7.2.0(stylelint@17.5.0(typescript@5.9.3)) + optionalDependencies: + postcss: 8.5.26 - stylelint-config-recommended@15.0.0(stylelint@16.16.0(typescript@5.8.3)): + stylelint-config-recommended@18.0.0(stylelint@17.5.0(typescript@5.9.3)): dependencies: - stylelint: 16.16.0(typescript@5.8.3) + stylelint: 17.5.0(typescript@5.9.3) - stylelint-config-standard-scss@14.0.0(postcss@8.5.3)(stylelint@16.16.0(typescript@5.8.3)): + stylelint-config-standard-scss@17.0.0(postcss@8.5.26)(stylelint@17.5.0(typescript@5.9.3)): dependencies: - stylelint: 16.16.0(typescript@5.8.3) - stylelint-config-recommended-scss: 14.1.0(postcss@8.5.3)(stylelint@16.16.0(typescript@5.8.3)) - stylelint-config-standard: 36.0.1(stylelint@16.16.0(typescript@5.8.3)) + stylelint: 17.5.0(typescript@5.9.3) + stylelint-config-recommended-scss: 17.0.1(postcss@8.5.26)(stylelint@17.5.0(typescript@5.9.3)) + stylelint-config-standard: 40.0.0(stylelint@17.5.0(typescript@5.9.3)) optionalDependencies: - postcss: 8.5.3 - - stylelint-config-standard@36.0.1(stylelint@16.16.0(typescript@5.8.3)): - dependencies: - stylelint: 16.16.0(typescript@5.8.3) - stylelint-config-recommended: 14.0.1(stylelint@16.16.0(typescript@5.8.3)) + postcss: 8.5.26 - stylelint-config-standard@37.0.0(stylelint@16.16.0(typescript@5.8.3)): + stylelint-config-standard@40.0.0(stylelint@17.5.0(typescript@5.9.3)): dependencies: - stylelint: 16.16.0(typescript@5.8.3) - stylelint-config-recommended: 15.0.0(stylelint@16.16.0(typescript@5.8.3)) + stylelint: 17.5.0(typescript@5.9.3) + stylelint-config-recommended: 18.0.0(stylelint@17.5.0(typescript@5.9.3)) - stylelint-scss@6.11.1(stylelint@16.16.0(typescript@5.8.3)): + stylelint-scss@7.2.0(stylelint@17.5.0(typescript@5.9.3)): dependencies: - css-tree: 3.1.0 + '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-syntax-patches-for-csstree': 1.1.8(css-tree@3.2.1) + '@csstools/css-tokenizer': 4.0.0 + css-tree: 3.2.1 is-plain-object: 5.0.0 - known-css-properties: 0.35.0 - mdn-data: 2.21.0 + known-css-properties: 0.37.0 postcss-media-query-parser: 0.2.3 postcss-resolve-nested-selector: 0.1.6 - postcss-selector-parser: 7.1.0 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 - stylelint: 16.16.0(typescript@5.8.3) + stylelint: 17.5.0(typescript@5.9.3) - stylelint@16.16.0(typescript@5.8.3): + stylelint@17.5.0(typescript@5.9.3): dependencies: - '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) - '@csstools/css-tokenizer': 3.0.3 - '@csstools/media-query-list-parser': 4.0.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) - '@csstools/selector-specificity': 5.0.0(postcss-selector-parser@7.1.0) - '@dual-bundle/import-meta-resolve': 4.1.0 - balanced-match: 2.0.0 + '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-syntax-patches-for-csstree': 1.1.8(css-tree@3.2.1) + '@csstools/css-tokenizer': 4.0.0 + '@csstools/media-query-list-parser': 5.0.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/selector-resolve-nested': 4.0.1(postcss-selector-parser@7.1.5) + '@csstools/selector-specificity': 6.0.0(postcss-selector-parser@7.1.5) colord: 2.9.3 - cosmiconfig: 9.0.0(typescript@5.8.3) - css-functions-list: 3.2.3 - css-tree: 3.1.0 - debug: 4.4.0 + cosmiconfig: 9.0.2(typescript@5.9.3) + css-functions-list: 3.3.3 + css-tree: 3.2.1 + debug: 4.4.3 fast-glob: 3.3.3 fastest-levenshtein: 1.0.16 - file-entry-cache: 10.0.8 + file-entry-cache: 11.1.5 global-modules: 2.0.0 - globby: 11.1.0 + globby: 16.2.4 globjoin: 0.1.4 - html-tags: 3.3.1 - ignore: 7.0.3 + html-tags: 5.1.0 + ignore: 7.0.6 + import-meta-resolve: 4.2.0 imurmurhash: 0.1.4 is-plain-object: 5.0.0 - known-css-properties: 0.35.0 - mathml-tag-names: 2.1.3 - meow: 13.2.0 + mathml-tag-names: 4.0.0 + meow: 14.1.0 micromatch: 4.0.8 normalize-path: 3.0.0 picocolors: 1.1.1 - postcss: 8.5.3 - postcss-resolve-nested-selector: 0.1.6 - postcss-safe-parser: 7.0.1(postcss@8.5.3) - postcss-selector-parser: 7.1.0 + postcss: 8.5.26 + postcss-safe-parser: 7.0.1(postcss@8.5.26) + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 - resolve-from: 5.0.0 - string-width: 4.2.3 - supports-hyperlinks: 3.2.0 + string-width: 8.2.2 + supports-hyperlinks: 4.5.0 svg-tags: 1.0.0 table: 6.9.0 - write-file-atomic: 5.0.1 + write-file-atomic: 7.0.1 transitivePeerDependencies: - supports-color - typescript + supports-color@10.2.2: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - supports-hyperlinks@3.2.0: + supports-color@8.1.1: dependencies: has-flag: 4.0.0 - supports-color: 7.2.0 - supports-preserve-symlinks-flag@1.0.0: {} + supports-hyperlinks@4.5.0: + dependencies: + has-flag: 5.0.1 + supports-color: 10.2.2 svg-tags@1.0.0: {} @@ -4049,20 +3716,30 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + temporal-polyfill@0.2.5: + dependencies: + temporal-spec: 0.2.4 + + temporal-spec@0.2.4: {} + tiny-emitter@2.1.0: {} - tmp@0.2.3: {} + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - tsconfig-paths@3.15.0: + tr46@0.0.3: {} + + tree-kill@1.2.2: {} + + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 + typescript: 5.9.3 tslib@2.8.1: {} @@ -4070,55 +3747,34 @@ snapshots: dependencies: prelude-ls: 1.2.1 - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.3 - es-errors: 1.3.0 - is-typed-array: 1.1.15 + type-fest@4.41.0: {} - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.4 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 + typed-function@4.2.1: {} - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.4 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 + typesafe-path@0.2.2: {} - typed-array-length@1.0.7: + typescript-auto-import-cache@0.3.6: dependencies: - call-bind: 1.0.8 - for-each: 0.3.4 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.0.0 - reflect.getprototypeof: 1.0.10 - - typed-function@4.2.1: {} + semver: 7.8.5 - typescript@5.8.3: {} - - unbox-primitive@1.1.0: + typescript-eslint@8.67.0(eslint@10.6.0)(typescript@5.9.3): dependencies: - call-bound: 1.0.3 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 + '@typescript-eslint/eslint-plugin': 8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.6.0)(typescript@5.9.3))(eslint@10.6.0)(typescript@5.9.3) + '@typescript-eslint/parser': 8.67.0(eslint@10.6.0)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.6.0)(typescript@5.9.3) + eslint: 10.6.0 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} - unicorn-magic@0.1.0: {} + unicorn-magic@0.3.0: {} - universalify@2.0.1: {} + unicorn-magic@0.4.0: {} - upath@2.0.1: {} + universalify@0.1.2: {} update-browserslist-db@1.1.2(browserslist@4.24.4): dependencies: @@ -4132,51 +3788,66 @@ snapshots: util-deprecate@1.0.2: {} - v8-compile-cache@2.4.0: {} + volar-service-html@0.0.71(@volar/language-service@2.4.28): + dependencies: + vscode-html-languageservice: 5.6.2 + vscode-languageserver-textdocument: 1.0.12 + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + + volar-service-typescript@0.0.71(@volar/language-service@2.4.28): + dependencies: + path-browserify: 1.0.1 + semver: 7.8.5 + typescript-auto-import-cache: 0.3.6 + vscode-languageserver-textdocument: 1.0.12 + vscode-nls: 5.2.0 + vscode-uri: 3.1.0 + optionalDependencies: + '@volar/language-service': 2.4.28 - wcwidth@1.0.1: + vscode-html-languageservice@5.6.2: dependencies: - defaults: 1.0.4 + '@vscode/l10n': 0.0.18 + vscode-languageserver-textdocument: 1.0.12 + vscode-languageserver-types: 3.18.0 + vscode-uri: 3.1.0 + + vscode-jsonrpc@8.2.0: {} - which-boxed-primitive@1.1.1: + vscode-jsonrpc@9.0.1: {} + + vscode-languageserver-protocol@3.17.5: dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 - which-builtin-type@1.2.1: + vscode-languageserver-protocol@3.18.2: dependencies: - call-bound: 1.0.3 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.18 + vscode-jsonrpc: 9.0.1 + vscode-languageserver-types: 3.18.0 + + vscode-languageserver-textdocument@1.0.12: {} - which-collection@1.0.2: + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver-types@3.18.0: {} + + vscode-languageserver@9.0.1: dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 + vscode-languageserver-protocol: 3.17.5 + + vscode-nls@5.2.0: {} + + vscode-uri@3.1.0: {} - which-typed-array@1.1.18: + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.3 - for-each: 0.3.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 + tr46: 0.0.3 + webidl-conversions: 3.0.1 which@1.3.1: dependencies: @@ -4188,17 +3859,14 @@ snapshots: word-wrap@1.2.5: {} - workerpool@6.5.1: {} - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - write-file-atomic@5.0.1: + write-file-atomic@7.0.1: dependencies: - imurmurhash: 0.1.4 signal-exit: 4.1.0 y18n@5.0.8: {} @@ -4218,5 +3886,3 @@ snapshots: yargs-parser: 21.1.1 yocto-queue@0.1.0: {} - - yocto-queue@1.1.1: {} diff --git a/stylint.config.mjs b/stylelint.config.mjs similarity index 100% rename from stylint.config.mjs rename to stylelint.config.mjs diff --git a/test/javascripts/acceptance/composer-test.js b/test/javascripts/acceptance/composer-test.js index 79afc32..ba2587f 100644 --- a/test/javascripts/acceptance/composer-test.js +++ b/test/javascripts/acceptance/composer-test.js @@ -1,4 +1,4 @@ -import { click,fillIn, visit, waitUntil } from "@ember/test-helpers"; +import { click, fillIn, visit, waitUntil } from "@ember/test-helpers"; import { test } from "qunit"; import { acceptance } from "discourse/tests/helpers/qunit-helpers"; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b157438 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "extends": "discourse/tsconfig-plugin", + "include": [ + "admin/assets/javascripts/**/*", + "assets/javascripts/**/*", + "test/javascripts/**/*", + "node_modules/discourse/declarations/**/*" + ], + "compilerOptions": { + "paths": { + "discourse/plugins/rollmaster/*": ["./assets/javascripts/*"], + "discourse/plugins/rollmaster/admin/*": [ + "./admin/assets/javascripts/admin/*" + ], + "admin/*": ["./node_modules/discourse/declarations/admin/*"], + "float-kit/*": ["./node_modules/discourse/declarations/float-kit/*"], + "select-kit/*": ["./node_modules/discourse/declarations/select-kit/*"], + "truth-helpers": [ + "./node_modules/discourse/declarations/truth-helpers/index.d.ts" + ], + "truth-helpers/*": [ + "./node_modules/discourse/declarations/truth-helpers/*" + ] + } + } +} From b8ee712f6e1ce147da72deb6173e25528e78d8d6 Mon Sep 17 00:00:00 2001 From: Steven Chang Date: Fri, 21 Aug 2026 22:51:24 +0000 Subject: [PATCH 15/15] test --- spec/system/roll_history_spec.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/system/roll_history_spec.rb b/spec/system/roll_history_spec.rb index e8fc2b0..0b372d2 100644 --- a/spec/system/roll_history_spec.rb +++ b/spec/system/roll_history_spec.rb @@ -28,9 +28,8 @@ topic_page.open_roll_history(post) expect(roll_history_modal).to be_open - expect(roll_history_modal.row_count).to eq(3) + expect(roll_history_modal.row_count).to eq(2) expect(roll_history_modal.entry_count(notation: "1d6", status: "Current")).to eq(1) - expect(roll_history_modal.entry_count(notation: "1d6", status: "Historical")).to eq(1) expect(roll_history_modal).to have_entry(notation: "1d8", status: "Historical") end