From 876b70a52d1220cacbcefaa8f049815bd3a545ef Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 4 May 2024 14:48:07 -0400 Subject: [PATCH 001/106] Refactor item/block models to use the same BlockModel class, matching how Minecraft does it --- src/hexdoc/cli/app.py | 17 +- src/hexdoc/graphics/render.py | 15 +- src/hexdoc/minecraft/model/__init__.py | 14 ++ src/hexdoc/minecraft/model/block.py | 147 ++++++++++++++++++ .../minecraft/{models => model}/blockstate.py | 0 src/hexdoc/minecraft/model/display.py | 54 +++++++ .../base_model.py => model/element.py} | 129 +-------------- src/hexdoc/minecraft/model/variable.py | 12 ++ src/hexdoc/minecraft/models/__init__.py | 11 -- src/hexdoc/minecraft/models/block.py | 54 ------- src/hexdoc/minecraft/models/item.py | 41 ----- src/hexdoc/minecraft/models/load.py | 25 --- src/hexdoc/model/__init__.py | 2 + 13 files changed, 249 insertions(+), 272 deletions(-) create mode 100644 src/hexdoc/minecraft/model/__init__.py create mode 100644 src/hexdoc/minecraft/model/block.py rename src/hexdoc/minecraft/{models => model}/blockstate.py (100%) create mode 100644 src/hexdoc/minecraft/model/display.py rename src/hexdoc/minecraft/{models/base_model.py => model/element.py} (56%) create mode 100644 src/hexdoc/minecraft/model/variable.py delete mode 100644 src/hexdoc/minecraft/models/__init__.py delete mode 100644 src/hexdoc/minecraft/models/block.py delete mode 100644 src/hexdoc/minecraft/models/item.py delete mode 100644 src/hexdoc/minecraft/models/load.py diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 5314ec1b..67c51717 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -31,8 +31,7 @@ TextureContext, ) from hexdoc.minecraft.assets.load_assets import render_block -from hexdoc.minecraft.models.item import ItemModel -from hexdoc.minecraft.models.load import load_model +from hexdoc.minecraft.model import BlockModel from hexdoc.patchouli import BookContext, FormattingContext from hexdoc.plugin import ModPluginWithBook from hexdoc.utils import git_root, setup_logging, write_to_path @@ -459,13 +458,17 @@ def render_model( if normals: debug |= DebugType.NORMALS + model_id_ = ResourceLocation.from_str(model_id) with ModResourceLoader.load_all(props, pm, export=False) as loader: - _, model = load_model(loader, ResourceLocation.from_str(model_id)) - while isinstance(model, ItemModel) and model.parent: - _, model = load_model(loader, model.parent) + _, model = BlockModel.load(loader, model_id_) - if isinstance(model, ItemModel): - raise ValueError(f"Invalid block id: {model_id}") + # TODO: reimplement + + # while isinstance(model, ItemModel) and model.parent: + # _, model = load_model(loader, model.parent) + + # if isinstance(model, ItemModel): + # raise ValueError(f"Invalid block id: {model_id}") with BlockRenderer(loader=loader, debug=debug) as renderer: renderer.render_block_model(model, output_path) diff --git a/src/hexdoc/graphics/render.py b/src/hexdoc/graphics/render.py index 7d3e234b..71c13f08 100644 --- a/src/hexdoc/graphics/render.py +++ b/src/hexdoc/graphics/render.py @@ -26,13 +26,13 @@ from hexdoc.graphics import glsl from hexdoc.minecraft.assets import AnimationMeta from hexdoc.minecraft.assets.animated import AnimationMetaTag -from hexdoc.minecraft.models import BlockModel -from hexdoc.minecraft.models.base_model import ( +from hexdoc.minecraft.model import ( + BlockModel, DisplayPosition, + Element, ElementFace, ElementFaceUV, FaceName, - ModelElement, ) from hexdoc.utils.types import Vec3, Vec4 @@ -81,12 +81,7 @@ def render_block_model( output_path: str | Path, ): if isinstance(model, ResourceLocation): - _, model = self.loader.load_resource( - type="assets", - folder="models", - id=model, - decode=BlockModel.model_validate_json, - ) + _, model = BlockModel.load(self.loader, model) model.load_parents_and_apply(self.loader) @@ -374,7 +369,7 @@ class BlockTextureInfo: @dataclass(kw_only=True) class BakedFace: - element: ModelElement + element: Element direction: FaceName face: ElementFace m_model: Matrix44 diff --git a/src/hexdoc/minecraft/model/__init__.py b/src/hexdoc/minecraft/model/__init__.py new file mode 100644 index 00000000..af939528 --- /dev/null +++ b/src/hexdoc/minecraft/model/__init__.py @@ -0,0 +1,14 @@ +__all__ = [ + "BlockModel", + "Blockstate", + "DisplayPosition", + "Element", + "ElementFace", + "ElementFaceUV", + "FaceName", +] + +from .block import BlockModel +from .blockstate import Blockstate +from .display import DisplayPosition +from .element import Element, ElementFace, ElementFaceUV, FaceName diff --git a/src/hexdoc/minecraft/model/block.py b/src/hexdoc/minecraft/model/block.py new file mode 100644 index 00000000..66c7889a --- /dev/null +++ b/src/hexdoc/minecraft/model/block.py @@ -0,0 +1,147 @@ +from __future__ import annotations + +from typing import Literal, Self + +from pydantic import Field, model_validator + +from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.model import IGNORE_EXTRA_CONFIG, HexdocModel + +from .display import DisplayPosition, DisplayPositionName +from .element import Element +from .variable import TextureVariable + + +class BlockModel(HexdocModel): + """Represents a Minecraft block (or item!!) model. + + https://minecraft.wiki/w/Tutorials/Models + """ + + model_config = IGNORE_EXTRA_CONFIG + + # common fields + + parent: ResourceLocation | None = None + """Loads a different model from the given path, in form of a resource location. + + If both "parent" and "elements" are set, the "elements" tag overrides the "elements" + tag from the previous model. + """ + display: dict[DisplayPositionName, DisplayPosition] = Field(default_factory=dict) + """Holds the different places where item models are displayed. + + `fixed` refers to item frames, while the rest are as their name states. + """ + textures: dict[str, TextureVariable | ResourceLocation] = Field( + default_factory=dict + ) + """Holds the textures of the model, in form of a resource location or can be another + texture variable.""" + elements: list[Element] | None = None + """Contains all the elements of the model. They can have only cubic forms. + + If both "parent" and "elements" are set, the "elements" tag overrides the "elements" + tag from the previous model. + """ + gui_light: Literal["front", "side"] = Field(None, validate_default=False) + """If set to `side` (default), the model is rendered like a block. + + If set to `front`, model is shaded like a flat item. + + Note: although the wiki only lists this field for item models, Minecraft sets it in + the models `minecraft:block/block` and `minecraft:block/calibrated_sculk_sensor`. + """ + + # blocks only + + ambientocclusion: bool = True + """Whether to use ambient occlusion or not. + + Note: only works on parent file. + """ + render_type: ResourceLocation | None = None + """Sets the rendering type for this model. + + https://docs.minecraftforge.net/en/latest/rendering/modelextensions/rendertypes/ + """ + + # items only + + overrides: list[ItemOverride] | None = None + """Determines cases in which a different model should be used based on item tags. + + All cases are evaluated in order from top to bottom and last predicate that matches + overrides. However, overrides are ignored if it has been already overridden once, + for example this avoids recursion on overriding to the same model. + """ + + @classmethod + def load(cls, loader: ModResourceLoader, model_id: ResourceLocation): + try: + return loader.load_resource( + type="assets", + folder="models", + id=model_id, + decode=cls.model_validate_json, + ) + except Exception as e: + e.add_note(f" note: {model_id=}") + raise + + def apply_parent(self, parent: Self): + self.parent = parent.parent + + # prefer current display/textures over parent + self.display = parent.display | self.display + self.textures = parent.textures | self.textures + + # only use parent elements if current model doesn't have elements + if self.elements is None: + self.elements = parent.elements + if not self._was_gui_light_set: + self.gui_light = parent.gui_light + + self.ambientocclusion = parent.ambientocclusion + self.render_type = self.render_type or parent.render_type + + def load_parents_and_apply(self, loader: ModResourceLoader): + while self.parent: + _, parent = loader.load_resource( + "assets", + "models", + self.parent, + decode=self.model_validate_json, + ) + self.apply_parent(parent) + + def resolve_texture_variables(self): + textures = dict[str, ResourceLocation]() + for name, value in self.textures.items(): + # TODO: is it possible for this to loop forever? + while not isinstance(value, ResourceLocation): + value = value.lstrip("#") + if value == name: + raise ValueError(f"Cyclic texture variable detected: {name}") + value = self.textures[value] + textures[name] = value + return textures + + @model_validator(mode="after") + def _set_default_gui_light(self): + self._was_gui_light_set = self.gui_light is not None # type: ignore + if not self._was_gui_light_set: + self.gui_light = "side" + return self + + +class ItemOverride(HexdocModel): + """An item model override case. + + https://minecraft.wiki/w/Tutorials/Models#Item_models + """ + + model: ResourceLocation + """The path to the model to use if the case is met.""" + predicate: dict[ResourceLocation, float] + """Item predicates that must be true for this model to be used.""" diff --git a/src/hexdoc/minecraft/models/blockstate.py b/src/hexdoc/minecraft/model/blockstate.py similarity index 100% rename from src/hexdoc/minecraft/models/blockstate.py rename to src/hexdoc/minecraft/model/blockstate.py diff --git a/src/hexdoc/minecraft/model/display.py b/src/hexdoc/minecraft/model/display.py new file mode 100644 index 00000000..938a2818 --- /dev/null +++ b/src/hexdoc/minecraft/model/display.py @@ -0,0 +1,54 @@ +from __future__ import annotations + +import math +from typing import Annotated, Literal + +from pydantic import Field + +from hexdoc.model import HexdocModel +from hexdoc.utils.types import Vec3, clamped + +DisplayPositionName = Literal[ + "thirdperson_righthand", + "thirdperson_lefthand", + "firstperson_righthand", + "firstperson_lefthand", + "gui", + "head", + "ground", + "fixed", +] +"""`fixed` refers to item frames, while the rest are as their name states.""" + + +class DisplayPosition(HexdocModel): + """Place where an item model is displayed. Holds its rotation, translation and scale + for the specified situation. + + Note that translations are applied to the model before rotations. + + If this is specified but not all of translation, rotation and scale are in it, the + others aren't inherited from the parent. (TODO: is this only for items? see wiki) + + https://minecraft.wiki/w/Tutorials/Models + """ + + rotation: Vec3 = (0, 0, 0) + """Specifies the rotation of the model according to the scheme [x, y, z].""" + translation: Vec3[Annotated[float, clamped(-80, 80)]] = (0, 0, 0) + """Specifies the position of the model according to the scheme [x, y, z]. + + The values are clamped between -80 and 80. + """ + scale: Vec3[Annotated[float, clamped(None, 4), Field(ge=0)]] = Field((0, 0, 0)) + """Specifies the scale of the model according to the scheme [x, y, z]. + + If the value is greater than 4, it is displayed as 4. + """ + + @property + def eulers(self) -> Vec3: + """Euler rotation vector, in radians.""" + rotation = tuple(math.radians(v) for v in self.rotation) + assert len(rotation) == 3 + return rotation diff --git a/src/hexdoc/minecraft/models/base_model.py b/src/hexdoc/minecraft/model/element.py similarity index 56% rename from src/hexdoc/minecraft/models/base_model.py rename to src/hexdoc/minecraft/model/element.py index 338936bf..e935873e 100644 --- a/src/hexdoc/minecraft/models/base_model.py +++ b/src/hexdoc/minecraft/model/element.py @@ -1,133 +1,18 @@ from __future__ import annotations import math -import re -from abc import ABC, abstractmethod -from typing import Annotated, Literal, Self +from typing import Annotated, Literal -from pydantic import AfterValidator, Field, model_validator +from pydantic import Field -from hexdoc.core import ResourceLocation from hexdoc.model import HexdocModel from hexdoc.model.base import IGNORE_EXTRA_CONFIG from hexdoc.utils.types import Vec3, Vec4, clamped +from .variable import TextureVariable -class BaseMinecraftModel(HexdocModel, ABC): - """Base class for Minecraft block/item models. - https://minecraft.wiki/w/Tutorials/Models - """ - - model_config = IGNORE_EXTRA_CONFIG - - parent: ResourceLocation | None = None - """Loads a different model from the given path, in form of a resource location. - - If both "parent" and "elements" are set, the "elements" tag overrides the "elements" - tag from the previous model. - """ - display: dict[DisplayPositionName, DisplayPosition] = Field(default_factory=dict) - """Holds the different places where item models are displayed. - - `fixed` refers to item frames, while the rest are as their name states. - """ - textures: dict[str, TextureVariable | ResourceLocation] = Field( - default_factory=dict - ) - """Holds the textures of the model, in form of a resource location or can be another - texture variable.""" - elements: list[ModelElement] | None = None - """Contains all the elements of the model. They can have only cubic forms. - - If both "parent" and "elements" are set, the "elements" tag overrides the "elements" - tag from the previous model. - """ - gui_light: Literal["front", "side"] = Field(None, validate_default=False) - """If set to `side` (default), the model is rendered like a block. - - If set to `front`, model is shaded like a flat item. - - Note: although the wiki only lists this field for item models, Minecraft sets it in - the models `minecraft:block/block` and `minecraft:block/calibrated_sculk_sensor`. - """ - - @abstractmethod - def apply_parent(self, parent: Self): - """Merge the parent model into this one.""" - self.parent = parent.parent - # prefer current display/textures over parent - self.display = parent.display | self.display - self.textures = parent.textures | self.textures - # only use parent elements if current model doesn't have elements - if self.elements is None: - self.elements = parent.elements - if not self._was_gui_light_set: - self.gui_light = parent.gui_light - - @model_validator(mode="after") - def _set_default_gui_light(self): - self._was_gui_light_set = self.gui_light is not None # type: ignore - if not self._was_gui_light_set: - self.gui_light = "side" - return self - - -def _validate_texture_variable(value: str): - assert re.fullmatch(r"#\w+", value) - return value - - -TextureVariable = Annotated[str, AfterValidator(_validate_texture_variable)] - - -DisplayPositionName = Literal[ - "thirdperson_righthand", - "thirdperson_lefthand", - "firstperson_righthand", - "firstperson_lefthand", - "gui", - "head", - "ground", - "fixed", -] -"""`fixed` refers to item frames, while the rest are as their name states.""" - - -class DisplayPosition(HexdocModel): - """Place where an item model is displayed. Holds its rotation, translation and scale - for the specified situation. - - Note that translations are applied to the model before rotations. - - If this is specified but not all of translation, rotation and scale are in it, the - others aren't inherited from the parent. (TODO: is this only for items? see wiki) - - https://minecraft.wiki/w/Tutorials/Models - """ - - rotation: Vec3 = (0, 0, 0) - """Specifies the rotation of the model according to the scheme [x, y, z].""" - translation: Vec3[Annotated[float, clamped(-80, 80)]] = (0, 0, 0) - """Specifies the position of the model according to the scheme [x, y, z]. - - The values are clamped between -80 and 80. - """ - scale: Vec3[Annotated[float, clamped(None, 4), Field(ge=0)]] = Field((0, 0, 0)) - """Specifies the scale of the model according to the scheme [x, y, z]. - - If the value is greater than 4, it is displayed as 4. - """ - - @property - def eulers(self) -> Vec3: - """Euler rotation vector, in radians.""" - rotation = tuple(math.radians(v) for v in self.rotation) - assert len(rotation) == 3 - return rotation - - -class ModelElement(HexdocModel): +class Element(HexdocModel): """An element of a block/item model. Must be cubic. https://minecraft.wiki/w/Tutorials/Models @@ -256,7 +141,7 @@ class ElementFaceUV(HexdocModel): rotation: Literal[0, 90, 180, 270] = 0 @classmethod - def default(cls, element: ModelElement, direction: FaceName): + def default(cls, element: Element, direction: FaceName): x1, y1, z1 = element.from_ x2, y2, z2 = element.to @@ -292,7 +177,3 @@ def get_v(self, index: Literal[0, 1, 2, 3]): def _get_shifted_index(self, index: Literal[0, 1, 2, 3]): return (index + self.rotation // 90) % 4 - - -# this is required to ensure BlockModel and ItemModel are fully defined -BaseMinecraftModel.model_rebuild() diff --git a/src/hexdoc/minecraft/model/variable.py b/src/hexdoc/minecraft/model/variable.py new file mode 100644 index 00000000..97579ce5 --- /dev/null +++ b/src/hexdoc/minecraft/model/variable.py @@ -0,0 +1,12 @@ +import re +from typing import Annotated + +from pydantic import AfterValidator + + +def _validate_texture_variable(value: str): + assert re.fullmatch(r"#\w+", value) + return value + + +TextureVariable = Annotated[str, AfterValidator(_validate_texture_variable)] diff --git a/src/hexdoc/minecraft/models/__init__.py b/src/hexdoc/minecraft/models/__init__.py deleted file mode 100644 index 532222f8..00000000 --- a/src/hexdoc/minecraft/models/__init__.py +++ /dev/null @@ -1,11 +0,0 @@ -__all__ = [ - "BlockModel", - "Blockstate", - "ItemModel", - "load_model", -] - -from .block import BlockModel -from .blockstate import Blockstate -from .item import ItemModel -from .load import load_model diff --git a/src/hexdoc/minecraft/models/block.py b/src/hexdoc/minecraft/models/block.py deleted file mode 100644 index b527d688..00000000 --- a/src/hexdoc/minecraft/models/block.py +++ /dev/null @@ -1,54 +0,0 @@ -from __future__ import annotations - -from typing import Self - -from typing_extensions import override - -from hexdoc.core import ModResourceLoader, ResourceLocation - -from .base_model import BaseMinecraftModel - - -class BlockModel(BaseMinecraftModel): - """Represents a Minecraft block model. - - https://minecraft.wiki/w/Tutorials/Models#Block_models - """ - - ambientocclusion: bool = True - """Whether to use ambient occlusion or not. - - Note: only works on parent file. - """ - render_type: ResourceLocation | None = None - """Sets the rendering type for this model. - - https://docs.minecraftforge.net/en/latest/rendering/modelextensions/rendertypes/ - """ - - @override - def apply_parent(self, parent: Self): - super().apply_parent(parent) - self.ambientocclusion = parent.ambientocclusion - self.render_type = self.render_type or parent.render_type - - def load_parents_and_apply(self, loader: ModResourceLoader): - while self.parent: - _, parent = loader.load_resource( - "assets", - "models", - self.parent, - decode=self.model_validate_json, - ) - self.apply_parent(parent) - - def resolve_texture_variables(self): - textures = dict[str, ResourceLocation]() - for name, value in self.textures.items(): - while not isinstance(value, ResourceLocation): - value = value.lstrip("#") - if value == name: - raise ValueError(f"Cyclic texture variable detected: {name}") - value = self.textures[value] - textures[name] = value - return textures diff --git a/src/hexdoc/minecraft/models/item.py b/src/hexdoc/minecraft/models/item.py deleted file mode 100644 index 520a91d1..00000000 --- a/src/hexdoc/minecraft/models/item.py +++ /dev/null @@ -1,41 +0,0 @@ -from __future__ import annotations - -from typing import Self - -from typing_extensions import override - -from hexdoc.core import ResourceLocation -from hexdoc.model import HexdocModel - -from .base_model import BaseMinecraftModel - - -class ItemModel(BaseMinecraftModel): - """Represents a Minecraft item model. - - https://minecraft.wiki/w/Tutorials/Models#Item_models - """ - - overrides: list[ItemModelOverride] | None = None - """Determines cases in which a different model should be used based on item tags. - - All cases are evaluated in order from top to bottom and last predicate that matches - overrides. However, overrides are ignored if it has been already overridden once, - for example this avoids recursion on overriding to the same model. - """ - - @override - def apply_parent(self, parent: Self): - super().apply_parent(parent) - - -class ItemModelOverride(HexdocModel): - """An item model override case. - - https://minecraft.wiki/w/Tutorials/Models#Item_models - """ - - model: ResourceLocation - """The path to the model to use if the case is met.""" - predicate: dict[ResourceLocation, float] - """Item predicates that must be true for this model to be used.""" diff --git a/src/hexdoc/minecraft/models/load.py b/src/hexdoc/minecraft/models/load.py deleted file mode 100644 index 2b61cb9d..00000000 --- a/src/hexdoc/minecraft/models/load.py +++ /dev/null @@ -1,25 +0,0 @@ -from hexdoc.core import ModResourceLoader, ResourceLocation - -from .block import BlockModel -from .item import ItemModel - - -def load_model(loader: ModResourceLoader, model_id: ResourceLocation): - match model_id.path.split("/")[0]: - case "block": - model_type = BlockModel - case "item": - model_type = ItemModel - case type_name: - raise ValueError(f"Unsupported type {type_name} for model {model_id}") - - try: - return loader.load_resource( - type="assets", - folder="models", - id=model_id, - decode=model_type.model_validate_json, - ) - except Exception as e: - e.add_note(f" note: {model_id=}") - raise diff --git a/src/hexdoc/model/__init__.py b/src/hexdoc/model/__init__.py index 4853b46a..57d17ef8 100644 --- a/src/hexdoc/model/__init__.py +++ b/src/hexdoc/model/__init__.py @@ -1,5 +1,6 @@ __all__ = [ "DEFAULT_CONFIG", + "IGNORE_EXTRA_CONFIG", "Color", "HexdocModel", "HexdocSettings", @@ -21,6 +22,7 @@ from .base import ( DEFAULT_CONFIG, + IGNORE_EXTRA_CONFIG, HexdocModel, HexdocSettings, HexdocTypeAdapter, From ed9e6e127c050b7a3232f56cb38921d61464e7a8 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 4 May 2024 15:04:51 -0400 Subject: [PATCH 002/106] Refactor some functions from hexdoc.graphics.render into separate files --- src/hexdoc/cli/app.py | 2 +- src/hexdoc/graphics/__init__.py | 6 + src/hexdoc/graphics/camera.py | 55 +++++++ src/hexdoc/graphics/lookups.py | 105 +++++++++++++ src/hexdoc/graphics/render.py | 168 +-------------------- src/hexdoc/graphics/utils.py | 30 ++++ src/hexdoc/minecraft/assets/load_assets.py | 2 +- 7 files changed, 203 insertions(+), 165 deletions(-) create mode 100644 src/hexdoc/graphics/camera.py create mode 100644 src/hexdoc/graphics/lookups.py create mode 100644 src/hexdoc/graphics/utils.py diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 67c51717..e7694c5d 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -22,7 +22,7 @@ dump_sitemap, load_sitemap, ) -from hexdoc.graphics.render import BlockRenderer, DebugType +from hexdoc.graphics import BlockRenderer, DebugType from hexdoc.jinja.render import create_jinja_env, get_templates, render_book from hexdoc.minecraft import I18n from hexdoc.minecraft.assets import ( diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index e69de29b..214c86fb 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -0,0 +1,6 @@ +__all__ = [ + "BlockRenderer", + "DebugType", +] + +from .render import BlockRenderer, DebugType diff --git a/src/hexdoc/graphics/camera.py b/src/hexdoc/graphics/camera.py new file mode 100644 index 00000000..c85105a9 --- /dev/null +++ b/src/hexdoc/graphics/camera.py @@ -0,0 +1,55 @@ +# pyright: reportUnknownMemberType=false + +from __future__ import annotations + +import math +from typing import cast + +from pyrr import Matrix44 + +from hexdoc.minecraft.model import FaceName + +from .lookups import get_direction_vec +from .utils import transform_vec + + +def orbit_camera(pitch: float, yaw: float): + """Both values are in degrees.""" + + eye = transform_vec( + (-64, 0, 0), + cast( + Matrix44, + Matrix44.identity(dtype="f4") + * Matrix44.from_y_rotation(math.radians(yaw)) + * Matrix44.from_z_rotation(math.radians(pitch)), + ), + ) + + up = transform_vec( + (-1, 0, 0), + cast( + Matrix44, + Matrix44.identity(dtype="f4") + * Matrix44.from_y_rotation(math.radians(yaw)) + * Matrix44.from_z_rotation(math.radians(90 - pitch)), + ), + ) + + return Matrix44.look_at( + eye=eye, + target=(0, 0, 0), + up=up, + dtype="f4", + ), eye + + +def direction_camera(pos: FaceName, up: FaceName = "up"): + """eg. north -> camera is placed to the north of the model, looking south""" + eye = get_direction_vec(pos, 64) + return Matrix44.look_at( + eye=eye, + target=(0, 0, 0), + up=get_direction_vec(up), + dtype="f4", + ), eye diff --git a/src/hexdoc/graphics/lookups.py b/src/hexdoc/graphics/lookups.py new file mode 100644 index 00000000..54ffdb91 --- /dev/null +++ b/src/hexdoc/graphics/lookups.py @@ -0,0 +1,105 @@ +# pyright: reportUnknownMemberType=false + +from __future__ import annotations + +from hexdoc.minecraft.model import FaceName +from hexdoc.utils.types import Vec3 + + +def get_face_verts(from_: Vec3, to: Vec3, direction: FaceName): + x1, y1, z1 = from_ + x2, y2, z2 = to + + # fmt: off + match direction: + case "south": + return [ + x2, y1, z2, + x2, y2, z2, + x1, y1, z2, + x2, y2, z2, + x1, y2, z2, + x1, y1, z2, + ] + case "east": + return [ + x2, y1, z1, + x2, y2, z1, + x2, y1, z2, + x2, y2, z1, + x2, y2, z2, + x2, y1, z2, + ] + case "down": + return [ + x2, y1, z1, + x2, y1, z2, + x1, y1, z2, + x2, y1, z1, + x1, y1, z2, + x1, y1, z1, + ] + case "west": + return [ + x1, y1, z2, + x1, y2, z2, + x1, y2, z1, + x1, y1, z2, + x1, y2, z1, + x1, y1, z1, + ] + case "north": + return [ + x2, y2, z1, + x2, y1, z1, + x1, y1, z1, + x2, y2, z1, + x1, y1, z1, + x1, y2, z1, + ] + case "up": + return [ + x2, y2, z1, + x1, y2, z1, + x2, y2, z2, + x1, y2, z1, + x1, y2, z2, + x2, y2, z2, + ] + # fmt: on + + +def get_face_uv_indices(direction: FaceName): + match direction: + case "south": + return (2, 3, 1, 3, 0, 1) + case "east": + return (2, 3, 1, 3, 0, 1) + case "down": + return (2, 3, 0, 2, 0, 1) + case "west": + return (2, 3, 0, 2, 0, 1) + case "north": + return (0, 1, 2, 0, 2, 3) + case "up": + return (3, 0, 2, 0, 1, 2) + + +def get_direction_vec(direction: FaceName, magnitude: float = 1): + match direction: + case "north": + return (0, 0, -magnitude) + case "south": + return (0, 0, magnitude) + case "west": + return (-magnitude, 0, 0) + case "east": + return (magnitude, 0, 0) + case "down": + return (0, -magnitude, 0) + case "up": + return (0, magnitude, 0) + + +def get_face_normals(direction: FaceName): + return 6 * get_direction_vec(direction) diff --git a/src/hexdoc/graphics/render.py b/src/hexdoc/graphics/render.py index 71c13f08..e96e79f7 100644 --- a/src/hexdoc/graphics/render.py +++ b/src/hexdoc/graphics/render.py @@ -3,14 +3,12 @@ from __future__ import annotations import logging -import math from dataclasses import dataclass from enum import Flag, auto from functools import cached_property from pathlib import Path -from typing import Any, Literal, cast +from typing import Any, cast -import importlib_resources as resources import moderngl as mgl import moderngl_window as mglw import numpy as np @@ -23,7 +21,6 @@ from pyrr import Matrix44 from hexdoc.core import ModResourceLoader, ResourceLocation -from hexdoc.graphics import glsl from hexdoc.minecraft.assets import AnimationMeta from hexdoc.minecraft.assets.animated import AnimationMetaTag from hexdoc.minecraft.model import ( @@ -36,6 +33,10 @@ ) from hexdoc.utils.types import Vec3, Vec4 +from .camera import direction_camera +from .lookups import get_face_normals, get_face_uv_indices, get_face_verts +from .utils import get_rotation_matrix, read_shader + logger = logging.getLogger(__name__) @@ -407,162 +408,3 @@ def sortkey(self, eye: Vec3): if self.is_opaque: return 0 return sum((a - b) ** 2 for a, b in zip(eye, self.position)) - - -def get_face_verts(from_: Vec3, to: Vec3, direction: FaceName): - x1, y1, z1 = from_ - x2, y2, z2 = to - - # fmt: off - match direction: - case "south": - return [ - x2, y1, z2, - x2, y2, z2, - x1, y1, z2, - x2, y2, z2, - x1, y2, z2, - x1, y1, z2, - ] - case "east": - return [ - x2, y1, z1, - x2, y2, z1, - x2, y1, z2, - x2, y2, z1, - x2, y2, z2, - x2, y1, z2, - ] - case "down": - return [ - x2, y1, z1, - x2, y1, z2, - x1, y1, z2, - x2, y1, z1, - x1, y1, z2, - x1, y1, z1, - ] - case "west": - return [ - x1, y1, z2, - x1, y2, z2, - x1, y2, z1, - x1, y1, z2, - x1, y2, z1, - x1, y1, z1, - ] - case "north": - return [ - x2, y2, z1, - x2, y1, z1, - x1, y1, z1, - x2, y2, z1, - x1, y1, z1, - x1, y2, z1, - ] - case "up": - return [ - x2, y2, z1, - x1, y2, z1, - x2, y2, z2, - x1, y2, z1, - x1, y2, z2, - x2, y2, z2, - ] - # fmt: on - - -def get_face_normals(direction: FaceName): - return 6 * get_direction_vec(direction) - - -def get_face_uv_indices(direction: FaceName): - match direction: - case "south": - return (2, 3, 1, 3, 0, 1) - case "east": - return (2, 3, 1, 3, 0, 1) - case "down": - return (2, 3, 0, 2, 0, 1) - case "west": - return (2, 3, 0, 2, 0, 1) - case "north": - return (0, 1, 2, 0, 2, 3) - case "up": - return (3, 0, 2, 0, 1, 2) - - -def orbit_camera(pitch: float, yaw: float): - """Both values are in degrees.""" - - eye = transform_vec( - (-64, 0, 0), - cast( - Matrix44, - Matrix44.identity(dtype="f4") - * Matrix44.from_y_rotation(math.radians(yaw)) - * Matrix44.from_z_rotation(math.radians(pitch)), - ), - ) - - up = transform_vec( - (-1, 0, 0), - cast( - Matrix44, - Matrix44.identity(dtype="f4") - * Matrix44.from_y_rotation(math.radians(yaw)) - * Matrix44.from_z_rotation(math.radians(90 - pitch)), - ), - ) - - return Matrix44.look_at( - eye=eye, - target=(0, 0, 0), - up=up, - dtype="f4", - ), eye - - -def transform_vec(vec: Vec3, matrix: Matrix44) -> Vec3: - return np.matmul((*vec, 1), matrix, dtype="f4")[:3] - - -def direction_camera(pos: FaceName, up: FaceName = "up"): - """eg. north -> camera is placed to the north of the model, looking south""" - eye = get_direction_vec(pos, 64) - return Matrix44.look_at( - eye=eye, - target=(0, 0, 0), - up=get_direction_vec(up), - dtype="f4", - ), eye - - -def get_direction_vec(direction: FaceName, magnitude: float = 1): - match direction: - case "north": - return (0, 0, -magnitude) - case "south": - return (0, 0, magnitude) - case "west": - return (-magnitude, 0, 0) - case "east": - return (magnitude, 0, 0) - case "down": - return (0, -magnitude, 0) - case "up": - return (0, magnitude, 0) - - -def read_shader(path: str, type: Literal["fragment", "vertex", "geometry"]): - file = resources.files(glsl) / path / f"{type}.glsl" - return file.read_text("utf-8") - - -def get_rotation_matrix(eulers: Vec3) -> Matrix44: - return cast( - Matrix44, - Matrix44.from_x_rotation(-eulers[0], "f4") - * Matrix44.from_y_rotation(-eulers[1], "f4") - * Matrix44.from_z_rotation(-eulers[2], "f4"), - ) diff --git a/src/hexdoc/graphics/utils.py b/src/hexdoc/graphics/utils.py new file mode 100644 index 00000000..7c4e1c0d --- /dev/null +++ b/src/hexdoc/graphics/utils.py @@ -0,0 +1,30 @@ +# pyright: reportUnknownMemberType=false + +from __future__ import annotations + +from typing import Literal, cast + +import importlib_resources as resources +import numpy as np +from pyrr import Matrix44 + +from hexdoc.graphics import glsl +from hexdoc.utils.types import Vec3 + + +def read_shader(path: str, type: Literal["fragment", "vertex", "geometry"]): + file = resources.files(glsl) / path / f"{type}.glsl" + return file.read_text("utf-8") + + +def transform_vec(vec: Vec3, matrix: Matrix44) -> Vec3: + return np.matmul((*vec, 1), matrix, dtype="f4")[:3] + + +def get_rotation_matrix(eulers: Vec3) -> Matrix44: + return cast( + Matrix44, + Matrix44.from_x_rotation(-eulers[0], "f4") + * Matrix44.from_y_rotation(-eulers[1], "f4") + * Matrix44.from_z_rotation(-eulers[2], "f4"), + ) diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index 3f372777..42463bce 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -14,7 +14,7 @@ PNGTextureOverride, TextureTextureOverride, ) -from hexdoc.graphics.render import BlockRenderer +from hexdoc.graphics import BlockRenderer from hexdoc.utils import PydanticURL from hexdoc.utils.context import ContextSource From c75f93d6f70ebd3645cccb3f3cd383c3e9798e6b Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 4 May 2024 16:39:14 -0400 Subject: [PATCH 003/106] Refactor BlockModel parent resolution --- src/hexdoc/cli/app.py | 2 +- src/hexdoc/graphics/render.py | 6 +-- src/hexdoc/minecraft/model/block.py | 71 ++++++++++++++++++++++------- 3 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index e7694c5d..3a2e9e01 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -460,7 +460,7 @@ def render_model( model_id_ = ResourceLocation.from_str(model_id) with ModResourceLoader.load_all(props, pm, export=False) as loader: - _, model = BlockModel.load(loader, model_id_) + _, model = BlockModel.load_and_resolve(loader, model_id_) # TODO: reimplement diff --git a/src/hexdoc/graphics/render.py b/src/hexdoc/graphics/render.py index e96e79f7..5a7d123a 100644 --- a/src/hexdoc/graphics/render.py +++ b/src/hexdoc/graphics/render.py @@ -82,13 +82,13 @@ def render_block_model( output_path: str | Path, ): if isinstance(model, ResourceLocation): - _, model = BlockModel.load(self.loader, model) + _, model = BlockModel.load_unresolved(self.loader, model) - model.load_parents_and_apply(self.loader) + model.resolve(self.loader) textures = { name: self.load_texture(texture_id) - for name, texture_id in model.resolve_texture_variables().items() + for name, texture_id in model.resolved_textures.items() } output_path = Path(output_path) diff --git a/src/hexdoc/minecraft/model/block.py b/src/hexdoc/minecraft/model/block.py index 66c7889a..31325278 100644 --- a/src/hexdoc/minecraft/model/block.py +++ b/src/hexdoc/minecraft/model/block.py @@ -1,11 +1,13 @@ from __future__ import annotations +from functools import cached_property from typing import Literal, Self -from pydantic import Field, model_validator +from pydantic import Field, PrivateAttr, model_validator from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.model import IGNORE_EXTRA_CONFIG, HexdocModel +from hexdoc.utils.types import PydanticOrderedSet, cast_nullable from .display import DisplayPosition, DisplayPositionName from .element import Element @@ -22,7 +24,7 @@ class BlockModel(HexdocModel): # common fields - parent: ResourceLocation | None = None + parent_id: ResourceLocation | None = Field(None, alias="parent") """Loads a different model from the given path, in form of a resource location. If both "parent" and "elements" are set, the "elements" tag overrides the "elements" @@ -76,8 +78,16 @@ class BlockModel(HexdocModel): for example this avoids recursion on overriding to the same model. """ + # internal fields + _is_generated_item: bool = PrivateAttr(False) + + @classmethod + def load_and_resolve(cls, loader: ModResourceLoader, model_id: ResourceLocation): + resource_dir, model = cls.load_unresolved(loader, model_id) + return resource_dir, model.resolve(loader) + @classmethod - def load(cls, loader: ModResourceLoader, model_id: ResourceLocation): + def load_unresolved(cls, loader: ModResourceLoader, model_id: ResourceLocation): try: return loader.load_resource( type="assets", @@ -89,8 +99,34 @@ def load(cls, loader: ModResourceLoader, model_id: ResourceLocation): e.add_note(f" note: {model_id=}") raise - def apply_parent(self, parent: Self): - self.parent = parent.parent + def resolve(self, loader: ModResourceLoader): + """Loads this model's parents and applies them in-place. + + Returns this model for convenience. + """ + loaded_parents = PydanticOrderedSet[ResourceLocation]() + while parent_id := self.parent_id: + if parent_id in loaded_parents: + raise ValueError( + "Recursive model parent chain: " + + " -> ".join(str(v) for v in [*loaded_parents, parent_id]) + ) + loaded_parents.add(parent_id) + + match parent_id: + case ResourceLocation("minecraft", "builtin/generated"): + self._is_generated_item = True + self.parent_id = None + case ResourceLocation("minecraft", "builtin/entity"): + raise ValueError(f"Unsupported model parent id: {parent_id}") + case _: + _, parent = self.load_unresolved(loader, parent_id) + self._apply_parent(parent) + + return self + + def _apply_parent(self, parent: Self): + self.parent_id = parent.parent_id # prefer current display/textures over parent self.display = parent.display | self.display @@ -99,23 +135,26 @@ def apply_parent(self, parent: Self): # only use parent elements if current model doesn't have elements if self.elements is None: self.elements = parent.elements + if not self._was_gui_light_set: self.gui_light = parent.gui_light self.ambientocclusion = parent.ambientocclusion + self.render_type = self.render_type or parent.render_type - def load_parents_and_apply(self, loader: ModResourceLoader): - while self.parent: - _, parent = loader.load_resource( - "assets", - "models", - self.parent, - decode=self.model_validate_json, - ) - self.apply_parent(parent) + @property + def is_resolved(self): + return self.parent_id is None + + @property + def is_generated_item(self): + return self._is_generated_item + + @cached_property + def resolved_textures(self): + assert self.is_resolved, "Cannot resolve textures for unresolved model" - def resolve_texture_variables(self): textures = dict[str, ResourceLocation]() for name, value in self.textures.items(): # TODO: is it possible for this to loop forever? @@ -129,7 +168,7 @@ def resolve_texture_variables(self): @model_validator(mode="after") def _set_default_gui_light(self): - self._was_gui_light_set = self.gui_light is not None # type: ignore + self._was_gui_light_set = cast_nullable(self.gui_light) is not None if not self._was_gui_light_set: self.gui_light = "side" return self From 754f5505c4af8370277f0c1fbfd6cdb33b9fe731 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 4 May 2024 18:37:14 -0400 Subject: [PATCH 004/106] Refactor rendering class in preparation for item model rendering --- src/hexdoc/cli/app.py | 36 ++----- src/hexdoc/graphics/__init__.py | 5 +- src/hexdoc/graphics/{render.py => block.py} | 88 +---------------- src/hexdoc/graphics/renderer.py | 104 ++++++++++++++++++++ src/hexdoc/graphics/utils.py | 7 ++ src/hexdoc/minecraft/assets/load_assets.py | 12 +-- src/hexdoc/minecraft/model/block.py | 7 +- 7 files changed, 136 insertions(+), 123 deletions(-) rename src/hexdoc/graphics/{render.py => block.py} (81%) create mode 100644 src/hexdoc/graphics/renderer.py diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 3a2e9e01..a3f46190 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -17,21 +17,12 @@ from hexdoc.__version__ import VERSION from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.data.metadata import HexdocMetadata -from hexdoc.data.sitemap import ( - delete_updated_books, - dump_sitemap, - load_sitemap, -) -from hexdoc.graphics import BlockRenderer, DebugType +from hexdoc.data.sitemap import delete_updated_books, dump_sitemap, load_sitemap +from hexdoc.graphics import DebugType, ModelRenderer from hexdoc.jinja.render import create_jinja_env, get_templates, render_book from hexdoc.minecraft import I18n -from hexdoc.minecraft.assets import ( - AnimatedTexture, - PNGTexture, - TextureContext, -) +from hexdoc.minecraft.assets import AnimatedTexture, PNGTexture, TextureContext from hexdoc.minecraft.assets.load_assets import render_block -from hexdoc.minecraft.model import BlockModel from hexdoc.patchouli import BookContext, FormattingContext from hexdoc.plugin import ModPluginWithBook from hexdoc.utils import git_root, setup_logging, write_to_path @@ -458,20 +449,11 @@ def render_model( if normals: debug |= DebugType.NORMALS - model_id_ = ResourceLocation.from_str(model_id) - with ModResourceLoader.load_all(props, pm, export=False) as loader: - _, model = BlockModel.load_and_resolve(loader, model_id_) - - # TODO: reimplement - - # while isinstance(model, ItemModel) and model.parent: - # _, model = load_model(loader, model.parent) - - # if isinstance(model, ItemModel): - # raise ValueError(f"Invalid block id: {model_id}") - - with BlockRenderer(loader=loader, debug=debug) as renderer: - renderer.render_block_model(model, output_path) + with ( + ModResourceLoader.load_all(props, pm, export=False) as loader, + ModelRenderer(loader=loader, debug=debug) as renderer, + ): + renderer.render_model(ResourceLocation.from_str(model_id), output_path) @app.command() @@ -494,7 +476,7 @@ def render_models( with ModResourceLoader.load_all(props, pm, export=export_resources) as loader: if model_ids: - with BlockRenderer(loader=loader, output_dir=output_dir) as renderer: + with ModelRenderer(loader=loader, output_dir=output_dir) as renderer: for model_id in model_ids: model_id = ResourceLocation.from_str(model_id) render_block(model_id, renderer, site_url) diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index 214c86fb..528fe49b 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -1,6 +1,7 @@ __all__ = [ - "BlockRenderer", "DebugType", + "ModelRenderer", ] -from .render import BlockRenderer, DebugType +from .renderer import ModelRenderer +from .utils import DebugType diff --git a/src/hexdoc/graphics/render.py b/src/hexdoc/graphics/block.py similarity index 81% rename from src/hexdoc/graphics/render.py rename to src/hexdoc/graphics/block.py index 5a7d123a..3ecaf38f 100644 --- a/src/hexdoc/graphics/render.py +++ b/src/hexdoc/graphics/block.py @@ -4,23 +4,19 @@ import logging from dataclasses import dataclass -from enum import Flag, auto from functools import cached_property from pathlib import Path -from typing import Any, cast +from typing import cast import moderngl as mgl -import moderngl_window as mglw import numpy as np from moderngl import Context, Program, Uniform from moderngl_window import WindowConfig from moderngl_window.context.headless import Window as HeadlessWindow from moderngl_window.opengl.vao import VAO from PIL import Image -from pydantic import ValidationError from pyrr import Matrix44 -from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.minecraft.assets import AnimationMeta from hexdoc.minecraft.assets.animated import AnimationMetaTag from hexdoc.minecraft.model import ( @@ -35,7 +31,7 @@ from .camera import direction_camera from .lookups import get_face_normals, get_face_uv_indices, get_face_verts -from .utils import get_rotation_matrix, read_shader +from .utils import DebugType, get_rotation_matrix, read_shader logger = logging.getLogger(__name__) @@ -48,85 +44,7 @@ LIGHT_FLAT = 0.98 -class DebugType(Flag): - NONE = 0 - AXES = auto() - NORMALS = auto() - - -@dataclass(kw_only=True) -class BlockRenderer: - loader: ModResourceLoader - output_dir: Path | None = None - debug: DebugType = DebugType.NONE - - def __post_init__(self): - self.window = HeadlessWindow( - size=(300, 300), - ) - mglw.activate_context(self.window) - - self.config = BlockRendererConfig(ctx=self.window.ctx, wnd=self.window) - - self.window.config = self.config - self.window.swap_buffers() - self.window.set_default_viewport() - - @property - def ctx(self): - return self.window.ctx - - def render_block_model( - self, - model: BlockModel | ResourceLocation, - output_path: str | Path, - ): - if isinstance(model, ResourceLocation): - _, model = BlockModel.load_unresolved(self.loader, model) - - model.resolve(self.loader) - - textures = { - name: self.load_texture(texture_id) - for name, texture_id in model.resolved_textures.items() - } - - output_path = Path(output_path) - if self.output_dir and not output_path.is_absolute(): - output_path = self.output_dir / output_path - - self.config.render_block(model, textures, output_path, self.debug) - - def load_texture(self, texture_id: ResourceLocation): - logger.debug(f"Loading texture: {texture_id}") - _, path = self.loader.find_resource("assets", "textures", texture_id + ".png") - - meta_path = path.with_suffix(".png.mcmeta") - if meta_path.is_file(): - logger.debug(f"Loading animation mcmeta: {meta_path}") - # FIXME: hack - try: - meta = AnimationMeta.model_validate_json(meta_path.read_bytes()) - except ValidationError as e: - logger.warning(f"Failed to parse animation meta for {texture_id}:\n{e}") - meta = None - else: - meta = None - - return BlockTextureInfo(path, meta) - - def destroy(self): - self.window.destroy() - - def __enter__(self): - return self - - def __exit__(self, *_: Any): - self.destroy() - return False - - -class BlockRendererConfig(WindowConfig): +class BlockRenderer(WindowConfig): def __init__(self, ctx: Context, wnd: HeadlessWindow): super().__init__(ctx, wnd) diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py new file mode 100644 index 00000000..7067e6d1 --- /dev/null +++ b/src/hexdoc/graphics/renderer.py @@ -0,0 +1,104 @@ +# pyright: reportUnknownMemberType=false + +from __future__ import annotations + +import logging +from dataclasses import dataclass +from pathlib import Path +from typing import Any + +import moderngl_window as mglw +from moderngl_window.context.headless import Window as HeadlessWindow +from pydantic import ValidationError + +from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.minecraft.assets import AnimationMeta +from hexdoc.minecraft.model import BlockModel + +from .block import BlockRenderer, BlockTextureInfo +from .utils import DebugType + +logger = logging.getLogger(__name__) + + +@dataclass(kw_only=True) +class ModelRenderer: + loader: ModResourceLoader + output_dir: Path | None = None + debug: DebugType = DebugType.NONE + + def __post_init__(self): + self.window = HeadlessWindow( + size=(300, 300), + ) + mglw.activate_context(self.window) + + self.block_renderer = BlockRenderer(ctx=self.window.ctx, wnd=self.window) + + self.window.config = self.block_renderer + self.window.swap_buffers() + self.window.set_default_viewport() + + @property + def ctx(self): + return self.window.ctx + + def render_model( + self, + model: BlockModel | ResourceLocation, + output_path: str | Path, + ): + if isinstance(model, ResourceLocation): + _, model = BlockModel.load_only(self.loader, model) + + model.resolve(self.loader) + + output_path = Path(output_path) + if self.output_dir and not output_path.is_absolute(): + output_path = self.output_dir / output_path + + if model.is_generated_item: + self._render_item(model, output_path) + else: + self._render_block(model, output_path) + + def _render_item(self, model: BlockModel, output_path: Path) -> None: + raise NotImplementedError() + + def _render_block(self, model: BlockModel, output_path: Path): + textures = self._load_textures(model.resolved_textures) + self.block_renderer.render_block(model, textures, output_path, self.debug) + + def _load_textures(self, textures: dict[str, ResourceLocation]): + return { + name: self._load_texture(texture_id) + for name, texture_id in textures.items() + } + + def _load_texture(self, texture_id: ResourceLocation): + logger.debug(f"Loading texture: {texture_id}") + _, path = self.loader.find_resource("assets", "textures", texture_id + ".png") + + meta_path = path.with_suffix(".png.mcmeta") + if meta_path.is_file(): + logger.debug(f"Loading animation mcmeta: {meta_path}") + # FIXME: hack + try: + meta = AnimationMeta.model_validate_json(meta_path.read_bytes()) + except ValidationError as e: + logger.warning(f"Failed to parse animation meta for {texture_id}:\n{e}") + meta = None + else: + meta = None + + return BlockTextureInfo(path, meta) + + def destroy(self): + self.window.destroy() + + def __enter__(self): + return self + + def __exit__(self, *_: Any): + self.destroy() + return False diff --git a/src/hexdoc/graphics/utils.py b/src/hexdoc/graphics/utils.py index 7c4e1c0d..4abff0c9 100644 --- a/src/hexdoc/graphics/utils.py +++ b/src/hexdoc/graphics/utils.py @@ -2,6 +2,7 @@ from __future__ import annotations +from enum import Flag, auto from typing import Literal, cast import importlib_resources as resources @@ -12,6 +13,12 @@ from hexdoc.utils.types import Vec3 +class DebugType(Flag): + NONE = 0 + AXES = auto() + NORMALS = auto() + + def read_shader(path: str, type: Literal["fragment", "vertex", "geometry"]): file = resources.files(glsl) / path / f"{type}.glsl" return file.read_text("utf-8") diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index 42463bce..ba3eb75b 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -14,7 +14,7 @@ PNGTextureOverride, TextureTextureOverride, ) -from hexdoc.graphics import BlockRenderer +from hexdoc.graphics import ModelRenderer from hexdoc.utils import PydanticURL from hexdoc.utils.context import ContextSource @@ -120,7 +120,7 @@ def load_item_models(self) -> Iterable[tuple[ResourceLocation, ModelItem]]: @cached_property def renderer(self): - return BlockRenderer( + return ModelRenderer( loader=self.loader, output_dir=self.render_dir, ) @@ -237,7 +237,7 @@ def load_texture( def load_and_render_item( model: ModelItem, loader: ModResourceLoader, - renderer: BlockRenderer, + renderer: ModelRenderer, gaslighting_items: Set[ResourceLocation], image_textures: dict[ResourceLocation, ImageTexture], site_url: URL, @@ -275,7 +275,7 @@ def load_and_render_item( # TODO: move to methods on a class returned by find_texture? def lookup_or_render_single_item( found_texture: FoundNormalTexture, - renderer: BlockRenderer, + renderer: ModelRenderer, image_textures: dict[ResourceLocation, ImageTexture], site_url: URL, ) -> SingleItemTexture: @@ -291,7 +291,7 @@ def lookup_or_render_single_item( def render_block( id: ResourceLocation, - renderer: BlockRenderer, + renderer: ModelRenderer, site_url: URL, ) -> SingleItemTexture: # FIXME: hack @@ -304,7 +304,7 @@ def render_block( out_path = f"assets/{id.namespace}/textures/{id_out_path}.png" try: - renderer.render_block_model(id, out_path) + renderer.render_model(id, out_path) except Exception as e: if renderer.loader.props.textures.strict: raise diff --git a/src/hexdoc/minecraft/model/block.py b/src/hexdoc/minecraft/model/block.py index 31325278..392555d5 100644 --- a/src/hexdoc/minecraft/model/block.py +++ b/src/hexdoc/minecraft/model/block.py @@ -83,11 +83,12 @@ class BlockModel(HexdocModel): @classmethod def load_and_resolve(cls, loader: ModResourceLoader, model_id: ResourceLocation): - resource_dir, model = cls.load_unresolved(loader, model_id) + resource_dir, model = cls.load_only(loader, model_id) return resource_dir, model.resolve(loader) @classmethod - def load_unresolved(cls, loader: ModResourceLoader, model_id: ResourceLocation): + def load_only(cls, loader: ModResourceLoader, model_id: ResourceLocation): + """Loads the given model without resolving it.""" try: return loader.load_resource( type="assets", @@ -120,7 +121,7 @@ def resolve(self, loader: ModResourceLoader): case ResourceLocation("minecraft", "builtin/entity"): raise ValueError(f"Unsupported model parent id: {parent_id}") case _: - _, parent = self.load_unresolved(loader, parent_id) + _, parent = self.load_only(loader, parent_id) self._apply_parent(parent) return self From fd1ea48da1edc0b346715813d4baceb2092a1722 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 4 May 2024 22:41:44 -0400 Subject: [PATCH 005/106] Partially implement animated item rendering --- .gitignore | 1 + src/hexdoc/graphics/block.py | 18 +--- src/hexdoc/graphics/renderer.py | 73 +++++++++++++--- src/hexdoc/graphics/texture.py | 98 ++++++++++++++++++++++ src/hexdoc/graphics/utils.py | 21 +++++ src/hexdoc/minecraft/assets/animated.py | 53 ++---------- src/hexdoc/minecraft/assets/load_assets.py | 4 +- src/hexdoc/minecraft/model/__init__.py | 4 + src/hexdoc/minecraft/model/animation.py | 91 ++++++++++++++++++++ src/hexdoc/minecraft/texture/__init__.py | 0 src/hexdoc/utils/iterators.py | 2 + 11 files changed, 293 insertions(+), 72 deletions(-) create mode 100644 src/hexdoc/graphics/texture.py create mode 100644 src/hexdoc/minecraft/model/animation.py create mode 100644 src/hexdoc/minecraft/texture/__init__.py diff --git a/.gitignore b/.gitignore index acdcb428..502646cf 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ __gradle_version__.py out/ .hexdoc*/ out.png +out.gif node_modules/ package-lock.json diff --git a/src/hexdoc/graphics/block.py b/src/hexdoc/graphics/block.py index 3ecaf38f..efc676f8 100644 --- a/src/hexdoc/graphics/block.py +++ b/src/hexdoc/graphics/block.py @@ -18,7 +18,6 @@ from pyrr import Matrix44 from hexdoc.minecraft.assets import AnimationMeta -from hexdoc.minecraft.assets.animated import AnimationMetaTag from hexdoc.minecraft.model import ( BlockModel, DisplayPosition, @@ -31,7 +30,7 @@ from .camera import direction_camera from .lookups import get_face_normals, get_face_uv_indices, get_face_verts -from .utils import DebugType, get_rotation_matrix, read_shader +from .utils import DebugType, get_height_and_layers, get_rotation_matrix, read_shader logger = logging.getLogger(__name__) @@ -162,20 +161,7 @@ def render_block( transparent_textures.add(name) # TODO: implement non-square animations, write test cases - match info.meta: - case AnimationMeta( - animation=AnimationMetaTag(height=frame_height), - ) if frame_height: - # animated with specified size - layers = image.height // frame_height - case AnimationMeta(): - # size is unspecified, assume it's square and verify later - frame_height = image.width - layers = image.height // frame_height - case None: - # non-animated - frame_height = image.height - layers = 1 + frame_height, layers = get_height_and_layers(image, info.meta) if frame_height * layers != image.height: raise RuntimeError( diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index 7067e6d1..fd30ffd4 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -9,9 +9,11 @@ import moderngl_window as mglw from moderngl_window.context.headless import Window as HeadlessWindow +from PIL import Image from pydantic import ValidationError from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.graphics.texture import ModelTexture from hexdoc.minecraft.assets import AnimationMeta from hexdoc.minecraft.model import BlockModel @@ -58,22 +60,71 @@ def render_model( output_path = self.output_dir / output_path if model.is_generated_item: - self._render_item(model, output_path) + return self._render_item(model, output_path) else: - self._render_block(model, output_path) - - def _render_item(self, model: BlockModel, output_path: Path) -> None: - raise NotImplementedError() + return self._render_block(model, output_path) def _render_block(self, model: BlockModel, output_path: Path): - textures = self._load_textures(model.resolved_textures) - self.block_renderer.render_block(model, textures, output_path, self.debug) - - def _load_textures(self, textures: dict[str, ResourceLocation]): - return { + textures = { name: self._load_texture(texture_id) - for name, texture_id in textures.items() + for name, texture_id in model.resolved_textures.items() } + self.block_renderer.render_block(model, textures, output_path, self.debug) + return output_path.suffix + + def _render_item(self, model: BlockModel, output_path: Path): + layers = sorted(self._load_layers(model), key=lambda v: v.index) + + animation_length = max(len(layer.frames) for layer in layers) + + frames = [ + self._render_item_frame(layers, tick) for tick in range(animation_length) + ] + + match frames: + case [image]: + image.save(output_path) + case [first, *rest]: + output_path = output_path.with_suffix(".gif") + first.save( + output_path, + save_all=True, + append_images=rest, + loop=0, # loop forever + duration=1000 / 20, + disposal=2, # restore to background color + interlace=False, + ) + case _: + # TODO: awful error message. + raise ValueError("No frames rendered!") + + return output_path.suffix + + def _render_item_frame(self, layers: list[ModelTexture], tick: int): + image = layers[0].get_frame(tick) + for texture in layers[1:]: + layer = texture.get_frame(tick) + if layer.size != image.size: + raise ValueError( + f"Mismatched size for layer {texture.index} at frame 0 " + + f"(expected {image.size}, got {layer.size})" + ) + image = Image.alpha_composite(image, layer) + return image + + def _load_layers(self, model: BlockModel): + for name, texture_id in model.resolved_textures.items(): + if not name.startswith("layer"): + continue + + index = name.removeprefix("layer") + if not index.isnumeric(): + continue + + texture = ModelTexture.load(self.loader, texture_id) + texture.index = int(index) + yield texture def _load_texture(self, texture_id: ResourceLocation): logger.debug(f"Loading texture: {texture_id}") diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py new file mode 100644 index 00000000..0daf09b8 --- /dev/null +++ b/src/hexdoc/graphics/texture.py @@ -0,0 +1,98 @@ +import logging +from dataclasses import dataclass +from functools import cached_property +from pathlib import Path + +from PIL import Image +from pydantic import ValidationError + +from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.minecraft.model import Animation, AnimationFrame, AnimationMeta +from hexdoc.utils import listify + +logger = logging.getLogger(__name__) + + +@dataclass(kw_only=True) +class ModelTexture: + index: int = -1 + image: Image.Image + animation: Animation | None + + @classmethod + def load(cls, loader: ModResourceLoader, texture_id: ResourceLocation): + logger.debug(f"Loading texture: {texture_id}") + _, path = loader.find_resource("assets", "textures", texture_id + ".png") + return cls( + image=Image.open(path).convert("RGBA"), + animation=cls._load_animation(path.with_suffix(".png.mcmeta")), + ) + + @classmethod + def _load_animation(cls, path: Path): + if not path.is_file(): + return None + + logger.debug(f"Loading animation mcmeta: {path}") + try: + meta = AnimationMeta.model_validate_json(path.read_bytes()) + return meta.animation + except ValidationError as e: + # FIXME: hack + logger.warning(f"Failed to parse animation meta ({path}):\n{e}") + return None + + @cached_property + def frame_height(self): + match self.animation: + case Animation(height=int()): + raise NotImplementedError() + case Animation() | None: + return self.image.width + + @cached_property + def frame_count(self): + count = self.image.height / self.frame_height + if not count.is_integer() or count < 1: + raise ValueError( + f"Invalid image dimensions (got {count=}):" + + f"width={self.image.width}, height={self.image.height}," + + f" frame_height={self.frame_height}" + ) + return int(count) + + def get_frame(self, tick: int): + if tick < 0: + raise ValueError(f"Expected tick >= 0, got {tick}") + return self.frames[tick % len(self.frames)] + + @cached_property + @listify + def frames(self): + """Returns a list of animation frames, where each frame lasts for one tick. + + If `animation` is None, just returns `[image]`. + """ + if self.animation is None: + yield self.image + return + + # TODO: implement width/height, interpolation + + frames = self.animation.frames or [ + AnimationFrame(index=i, time=self.animation.frametime) + for i in range(self.frame_count) + ] + + for frame in frames: + if frame.index >= self.frame_count: + raise ValueError( + f"Invalid frame index (expected <{self.frame_count}): {frame}" + ) + + start_y = self.frame_height * frame.index + end_y = start_y + self.frame_height + frame_image = self.image.crop((0, start_y, self.image.width, end_y)) + + for _ in range(frame.time): + yield frame_image diff --git a/src/hexdoc/graphics/utils.py b/src/hexdoc/graphics/utils.py index 4abff0c9..b05293a8 100644 --- a/src/hexdoc/graphics/utils.py +++ b/src/hexdoc/graphics/utils.py @@ -7,9 +7,11 @@ import importlib_resources as resources import numpy as np +from PIL.Image import Image from pyrr import Matrix44 from hexdoc.graphics import glsl +from hexdoc.minecraft.model import Animation, AnimationMeta from hexdoc.utils.types import Vec3 @@ -35,3 +37,22 @@ def get_rotation_matrix(eulers: Vec3) -> Matrix44: * Matrix44.from_y_rotation(-eulers[1], "f4") * Matrix44.from_z_rotation(-eulers[2], "f4"), ) + + +# TODO: remove +def get_height_and_layers(image: Image, meta: AnimationMeta | None): + match meta: + case AnimationMeta( + animation=Animation(height=frame_height), + ) if frame_height: + # animated with specified size + layers = image.height // frame_height + case AnimationMeta(): + # size is unspecified, assume it's square and verify later + frame_height = image.width + layers = image.height // frame_height + case None: + # non-animated + frame_height = image.height + layers = 1 + return frame_height, layers diff --git a/src/hexdoc/minecraft/assets/animated.py b/src/hexdoc/minecraft/assets/animated.py index fde43861..3207a995 100644 --- a/src/hexdoc/minecraft/assets/animated.py +++ b/src/hexdoc/minecraft/assets/animated.py @@ -1,31 +1,15 @@ -from functools import cached_property -from typing import Any, Literal, Self +from __future__ import annotations -from pydantic import Field +from functools import cached_property +from typing import Any, Self from hexdoc.model import HexdocModel from hexdoc.utils.types import PydanticURL +from ..model.animation import AnimationMeta from .textures import BaseTexture -class AnimationMetaFrame(HexdocModel): - index: int | None = None - time: int | None = None - - -class AnimationMetaTag(HexdocModel): - interpolate: Literal[False] = False # TODO: handle interpolation - width: None = None # TODO: handle non-square textures - height: None = None - frametime: int = 1 - frames: list[int | AnimationMetaFrame] = Field(default_factory=list) - - -class AnimationMeta(HexdocModel): - animation: AnimationMetaTag - - class AnimatedTextureFrame(HexdocModel): index: int start: int @@ -63,35 +47,16 @@ def time_seconds(self): @cached_property def time(self): - return sum(time for _, time in self._normalized_frames) + return sum(frame.time for frame in self.meta.animation.frames) @property def frames(self): start = 0 - for index, time in self._normalized_frames: + for frame in self.meta.animation.frames: yield AnimatedTextureFrame( - index=index, + index=frame.index, start=start, - time=time, + time=frame.time, animation_time=self.time, ) - start += time - - @property - def _normalized_frames(self): - """index, time""" - animation = self.meta.animation - - for i, frame in enumerate(animation.frames): - match frame: - case int(index): - time = None - case AnimationMetaFrame(index=index, time=time): - pass - - if index is None: - index = i - if time is None: - time = animation.frametime - - yield index, time + start += frame.time diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index ba3eb75b..069daecf 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -304,7 +304,9 @@ def render_block( out_path = f"assets/{id.namespace}/textures/{id_out_path}.png" try: - renderer.render_model(id, out_path) + # FIXME: scuffed + suffix = renderer.render_model(id, out_path) + out_path = out_path.removesuffix(".png") + suffix except Exception as e: if renderer.loader.props.textures.strict: raise diff --git a/src/hexdoc/minecraft/model/__init__.py b/src/hexdoc/minecraft/model/__init__.py index af939528..4a4c6d06 100644 --- a/src/hexdoc/minecraft/model/__init__.py +++ b/src/hexdoc/minecraft/model/__init__.py @@ -1,4 +1,7 @@ __all__ = [ + "Animation", + "AnimationFrame", + "AnimationMeta", "BlockModel", "Blockstate", "DisplayPosition", @@ -8,6 +11,7 @@ "FaceName", ] +from .animation import Animation, AnimationFrame, AnimationMeta from .block import BlockModel from .blockstate import Blockstate from .display import DisplayPosition diff --git a/src/hexdoc/minecraft/model/animation.py b/src/hexdoc/minecraft/model/animation.py new file mode 100644 index 00000000..82f18065 --- /dev/null +++ b/src/hexdoc/minecraft/model/animation.py @@ -0,0 +1,91 @@ +from __future__ import annotations + +from typing import Any + +from pydantic import Field, ValidationInfo, field_validator, model_validator + +from hexdoc.model import HexdocModel +from hexdoc.utils.types import cast_nullable + + +class AnimationMeta(HexdocModel): + """Animated texture `.mcmeta` file. + + Block, item, particle, painting, item frame, and status effect icon + (`assets/minecraft/textures/mob_effect`) textures support animation by placing each + additional frame below the last. The animation is then controlled using a `.mcmeta` + file in JSON format with the same name and `.png` at the end of the filename, in the + same directory. For example, the `.mcmeta` file for `stone.png` would be + `stone.png.mcmeta`. + + https://minecraft.wiki/w/Resource_pack#Animation + """ + + animation: Animation + """Contains data for the animation.""" + + +class Animation(HexdocModel): + """https://minecraft.wiki/w/Resource_pack#Animation""" + + interpolate: bool = False + """If true, generate additional frames between frames with a frame time greater than + 1 between them.""" + width: int | None = Field(None, ge=1) + """The width of the tile, as a direct ratio rather than in pixels. + + This is unused in vanilla's files but can be used by resource packs to have + frames that are not perfect squares. + """ + height: int | None = Field(None, ge=1) + """The height of the tile as a ratio rather than in pixels. + + This is unused in vanilla's files but can be used by resource packs to have + frames that are not perfect squares. + """ + frametime: int = Field(1, ge=1) + """Sets the default time for each frame in increments of one game tick.""" + frames: list[AnimationFrame] = Field(default_factory=list) + """Contains a list of frames. + + Integer values are a number corresponding to position of a frame from the top, + with the top frame being 0. + + Defaults to displaying all the frames from top to bottom. + """ + + @field_validator("width", "height", mode="after") + @classmethod + def _raise_not_implemented(cls, value: int | None, info: ValidationInfo): + if value is not None: + raise ValueError( + f"Field {info.field_name} is not currently supported" + + f" (expected None, got {value})" + ) + return value + + @model_validator(mode="after") + def _late_init_frames(self): + for i, frame in enumerate(self.frames): + if cast_nullable(frame.index) is None: + frame.index = i + if cast_nullable(frame.time) is None: + frame.time = self.frametime + return self + + +class AnimationFrame(HexdocModel): + index: int = Field(None, ge=0, validate_default=False) + """A number corresponding to position of a frame from the top, with the top + frame being 0.""" + time: int = Field(None, ge=1, validate_default=False) + """The time in ticks to show this frame.""" + + @model_validator(mode="before") + @classmethod + def _convert_from_int(cls, value: Any): + match value: + case int(): + return {"index": value} + case _: + return value diff --git a/src/hexdoc/minecraft/texture/__init__.py b/src/hexdoc/minecraft/texture/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/hexdoc/utils/iterators.py b/src/hexdoc/utils/iterators.py index ac24bc41..24a961aa 100644 --- a/src/hexdoc/utils/iterators.py +++ b/src/hexdoc/utils/iterators.py @@ -18,6 +18,8 @@ def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> Iterator[_T]: def listify(f: Callable[_P, Iterator[_T]]) -> Callable[_P, list[_T]]: + """Converts an iterator to a function returning a list.""" + @functools.wraps(f) def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> list[_T]: return list(f(*args, **kwargs)) From 3a5a42de2f6a708401969c2013300dd5e62eb400 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 4 May 2024 23:16:50 -0400 Subject: [PATCH 006/106] Implement texture interpolation --- .../example/models/item/example_item.json | 5 ++- src/hexdoc/graphics/texture.py | 32 ++++++++++++------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/examples/model_rendering/resources/assets/example/models/item/example_item.json b/examples/model_rendering/resources/assets/example/models/item/example_item.json index f866099e..a08376f3 100644 --- a/examples/model_rendering/resources/assets/example/models/item/example_item.json +++ b/examples/model_rendering/resources/assets/example/models/item/example_item.json @@ -1,3 +1,6 @@ { - "parent": "minecraft:block/stone" + "parent": "item/generated", + "textures": { + "layer0": "minecraft:block/command_block_front" + } } diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index 0daf09b8..4980feb6 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -84,15 +84,23 @@ def frames(self): for i in range(self.frame_count) ] - for frame in frames: - if frame.index >= self.frame_count: - raise ValueError( - f"Invalid frame index (expected <{self.frame_count}): {frame}" - ) - - start_y = self.frame_height * frame.index - end_y = start_y + self.frame_height - frame_image = self.image.crop((0, start_y, self.image.width, end_y)) - - for _ in range(frame.time): - yield frame_image + frame_images = [(frame, self._get_frame_image(frame)) for frame in frames] + + for i, (frame, image) in enumerate(frame_images): + # wrap around so it interpolates back to the start of the loop + _, next_image = frame_images[(i + 1) % len(frame_images)] + + for i in range(frame.time): + if self.animation.interpolate: + yield Image.blend(image, next_image, i / frame.time) + else: + yield image + + def _get_frame_image(self, frame: AnimationFrame): + if frame.index >= self.frame_count: + raise ValueError( + f"Invalid frame index (expected <{self.frame_count}): {frame}" + ) + start_y = self.frame_height * frame.index + end_y = start_y + self.frame_height + return self.image.crop((0, start_y, self.image.width, end_y)) From a41e406769b2b9cc353a3594cac8df4a4d75641e Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 4 May 2024 23:33:40 -0400 Subject: [PATCH 007/106] Implement block/item size configuration, refactor ModelTexture.index for clarity --- src/hexdoc/cli/app.py | 8 +++++++- src/hexdoc/graphics/renderer.py | 16 ++++++++++++---- src/hexdoc/graphics/texture.py | 4 ++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index a3f46190..9d997374 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -438,6 +438,7 @@ def render_model( output_path: Annotated[Path, Option("--output", "-o")] = Path("out.png"), axes: bool = False, normals: bool = False, + size: Optional[int] = None, ): """Use hexdoc's block rendering to render an item or block model.""" set_default_env() @@ -451,7 +452,12 @@ def render_model( with ( ModResourceLoader.load_all(props, pm, export=False) as loader, - ModelRenderer(loader=loader, debug=debug) as renderer, + ModelRenderer( + loader=loader, + debug=debug, + block_size=size, + item_size=size, + ) as renderer, ): renderer.render_model(ResourceLocation.from_str(model_id), output_path) diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index fd30ffd4..06fb1ff1 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -10,6 +10,7 @@ import moderngl_window as mglw from moderngl_window.context.headless import Window as HeadlessWindow from PIL import Image +from PIL.Image import Resampling from pydantic import ValidationError from hexdoc.core import ModResourceLoader, ResourceLocation @@ -28,10 +29,12 @@ class ModelRenderer: loader: ModResourceLoader output_dir: Path | None = None debug: DebugType = DebugType.NONE + block_size: int | None = None + item_size: int | None = None def __post_init__(self): self.window = HeadlessWindow( - size=(300, 300), + size=(self.block_size or 300,) * 2, ) mglw.activate_context(self.window) @@ -73,7 +76,7 @@ def _render_block(self, model: BlockModel, output_path: Path): return output_path.suffix def _render_item(self, model: BlockModel, output_path: Path): - layers = sorted(self._load_layers(model), key=lambda v: v.index) + layers = sorted(self._load_layers(model), key=lambda tex: tex.layer_index) animation_length = max(len(layer.frames) for layer in layers) @@ -103,14 +106,19 @@ def _render_item(self, model: BlockModel, output_path: Path): def _render_item_frame(self, layers: list[ModelTexture], tick: int): image = layers[0].get_frame(tick) + for texture in layers[1:]: layer = texture.get_frame(tick) if layer.size != image.size: raise ValueError( - f"Mismatched size for layer {texture.index} at frame 0 " + f"Mismatched size for layer {texture.layer_index} at frame 0 " + f"(expected {image.size}, got {layer.size})" ) image = Image.alpha_composite(image, layer) + + if self.item_size: + image = image.resize((self.item_size, self.item_size), Resampling.NEAREST) + return image def _load_layers(self, model: BlockModel): @@ -123,7 +131,7 @@ def _load_layers(self, model: BlockModel): continue texture = ModelTexture.load(self.loader, texture_id) - texture.index = int(index) + texture.layer_index = int(index) yield texture def _load_texture(self, texture_id: ResourceLocation): diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index 4980feb6..ffa74664 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -15,9 +15,9 @@ @dataclass(kw_only=True) class ModelTexture: - index: int = -1 image: Image.Image animation: Animation | None + layer_index: int = -1 @classmethod def load(cls, loader: ModResourceLoader, texture_id: ResourceLocation): @@ -77,7 +77,7 @@ def frames(self): yield self.image return - # TODO: implement width/height, interpolation + # TODO: implement width/height frames = self.animation.frames or [ AnimationFrame(index=i, time=self.animation.frametime) From ce3f1d61b14237d8442eb29d8fb7888b61d1ab15 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 00:23:03 -0400 Subject: [PATCH 008/106] Implement animated block rendering!! --- src/hexdoc/graphics/block.py | 65 +++++++++++++++------------------ src/hexdoc/graphics/renderer.py | 63 +++++++++++--------------------- src/hexdoc/graphics/texture.py | 19 +++++++--- src/hexdoc/graphics/utils.py | 21 ----------- 4 files changed, 65 insertions(+), 103 deletions(-) diff --git a/src/hexdoc/graphics/block.py b/src/hexdoc/graphics/block.py index efc676f8..3c0db773 100644 --- a/src/hexdoc/graphics/block.py +++ b/src/hexdoc/graphics/block.py @@ -5,7 +5,6 @@ import logging from dataclasses import dataclass from functools import cached_property -from pathlib import Path from typing import cast import moderngl as mgl @@ -17,7 +16,6 @@ from PIL import Image from pyrr import Matrix44 -from hexdoc.minecraft.assets import AnimationMeta from hexdoc.minecraft.model import ( BlockModel, DisplayPosition, @@ -30,7 +28,8 @@ from .camera import direction_camera from .lookups import get_face_normals, get_face_uv_indices, get_face_verts -from .utils import DebugType, get_height_and_layers, get_rotation_matrix, read_shader +from .texture import ModelTexture +from .utils import DebugType, get_rotation_matrix, read_shader logger = logging.getLogger(__name__) @@ -80,7 +79,6 @@ def __init__(self, ctx: Context, wnd: HeadlessWindow): self.uniform("m_proj").write(self.projection) self.uniform("m_camera").write(self.camera) - self.uniform("layer").value = 0 # TODO: implement animations for i, (direction, diffuse) in enumerate(self.lights): self.uniform(f"lights[{i}].direction").value = direction @@ -128,8 +126,7 @@ def __init__(self, ctx: Context, wnd: HeadlessWindow): def render_block( self, model: BlockModel, - texture_vars: dict[str, BlockTextureInfo], - output_path: Path, + texture_vars: dict[str, ModelTexture], debug: DebugType = DebugType.NONE, ): if not model.elements: @@ -149,35 +146,30 @@ def render_block( texture_locs = dict[str, int]() transparent_textures = set[str]() - for i, (name, info) in enumerate(texture_vars.items()): + for i, (name, texture) in enumerate(texture_vars.items()): texture_locs[name] = i - logger.debug(f"Loading texture {name}: {info}") - image = Image.open(info.image_path).convert("RGBA") + image = texture.image + frame_height = texture.frame_height + layers = len(texture.frames) min_alpha, _ = cast(tuple[int, int], image.getextrema()[3]) if min_alpha < 255: logger.debug(f"Transparent texture: {name} ({min_alpha=})") transparent_textures.add(name) - # TODO: implement non-square animations, write test cases - frame_height, layers = get_height_and_layers(image, info.meta) - - if frame_height * layers != image.height: - raise RuntimeError( - f"Invalid texture size for variable #{name}:" - + f" {frame_height}x{layers} != {image.height}" - + f"\n {info}" - ) + data = bytes() + for frame in texture.frames: + data += frame.tobytes() logger.debug(f"Texture array: {image.width=}, {frame_height=}, {layers=}") - texture = self.ctx.texture_array( + texture_array = self.ctx.texture_array( size=(image.width, frame_height, layers), components=4, - data=image.tobytes(), + data=data, ) - texture.filter = (mgl.NEAREST, mgl.NEAREST) - texture.use(i) + texture_array.filter = (mgl.NEAREST, mgl.NEAREST) + texture_array.use(i) # transform entire model @@ -222,7 +214,8 @@ def render_block( direction=direction, face=face, m_model=element_transform, - texture0=texture_locs[face.texture_name], + texture_loc=texture_locs[face.texture_name], + texture=texture_vars[face.texture_name], is_opaque=face.texture_name not in transparent_textures, ) baked_faces.append(baked_face) @@ -230,9 +223,19 @@ def render_block( # TODO: use a map if this is actually slow baked_faces.sort(key=lambda face: face.sortkey(self.eye)) + animation_length = max(len(face.texture.frames) for face in baked_faces) + return [ + self._render_frame(baked_faces, debug, animation_tick) + for animation_tick in range(animation_length) + ] + + def _render_frame(self, baked_faces: list[BakedFace], debug: DebugType, tick: int): + self.wnd.clear() + for face in baked_faces: self.uniform("m_model").write(face.m_model) - self.uniform("texture0").value = face.texture0 + self.uniform("texture0").value = face.texture_loc + self.uniform("layer").value = face.texture.get_frame_index(tick) face.vao.render(self.face_prog) @@ -249,16 +252,13 @@ def render_block( self.ctx.finish() - # save to file - image = Image.frombytes( mode="RGBA", size=self.wnd.fbo.size, data=self.wnd.fbo.read(components=4), ).transpose(Image.FLIP_TOP_BOTTOM) - output_path.parent.mkdir(parents=True, exist_ok=True) - image.save(output_path, format="png") + return image def uniform(self, name: str, program: Program | None = None): program = program or self.face_prog @@ -266,19 +266,14 @@ def uniform(self, name: str, program: Program | None = None): return uniform -@dataclass -class BlockTextureInfo: - image_path: Path - meta: AnimationMeta | None - - @dataclass(kw_only=True) class BakedFace: element: Element direction: FaceName face: ElementFace m_model: Matrix44 - texture0: float + texture_loc: float + texture: ModelTexture is_opaque: bool def __post_init__(self): diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index 06fb1ff1..15c2d04f 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -11,14 +11,12 @@ from moderngl_window.context.headless import Window as HeadlessWindow from PIL import Image from PIL.Image import Resampling -from pydantic import ValidationError from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.graphics.texture import ModelTexture -from hexdoc.minecraft.assets import AnimationMeta from hexdoc.minecraft.model import BlockModel -from .block import BlockRenderer, BlockTextureInfo +from .block import BlockRenderer from .utils import DebugType logger = logging.getLogger(__name__) @@ -63,27 +61,11 @@ def render_model( output_path = self.output_dir / output_path if model.is_generated_item: - return self._render_item(model, output_path) + frames = self._render_item(model) else: - return self._render_block(model, output_path) - - def _render_block(self, model: BlockModel, output_path: Path): - textures = { - name: self._load_texture(texture_id) - for name, texture_id in model.resolved_textures.items() - } - self.block_renderer.render_block(model, textures, output_path, self.debug) - return output_path.suffix - - def _render_item(self, model: BlockModel, output_path: Path): - layers = sorted(self._load_layers(model), key=lambda tex: tex.layer_index) - - animation_length = max(len(layer.frames) for layer in layers) - - frames = [ - self._render_item_frame(layers, tick) for tick in range(animation_length) - ] + frames = self._render_block(model) + output_path.mkdir(parents=True, exist_ok=True) match frames: case [image]: image.save(output_path) @@ -96,7 +78,6 @@ def _render_item(self, model: BlockModel, output_path: Path): loop=0, # loop forever duration=1000 / 20, disposal=2, # restore to background color - interlace=False, ) case _: # TODO: awful error message. @@ -104,6 +85,24 @@ def _render_item(self, model: BlockModel, output_path: Path): return output_path.suffix + def _render_block(self, model: BlockModel): + textures = { + name: ModelTexture.load(self.loader, texture_id) + for name, texture_id in model.resolved_textures.items() + } + return self.block_renderer.render_block(model, textures, self.debug) + + def _render_item(self, model: BlockModel): + layers = sorted( + self._load_layers(model), + key=lambda tex: tex.layer_index, + ) + animation_length = max(len(layer.frames) for layer in layers) + return [ + self._render_item_frame(layers, animation_tick) + for animation_tick in range(animation_length) + ] + def _render_item_frame(self, layers: list[ModelTexture], tick: int): image = layers[0].get_frame(tick) @@ -134,24 +133,6 @@ def _load_layers(self, model: BlockModel): texture.layer_index = int(index) yield texture - def _load_texture(self, texture_id: ResourceLocation): - logger.debug(f"Loading texture: {texture_id}") - _, path = self.loader.find_resource("assets", "textures", texture_id + ".png") - - meta_path = path.with_suffix(".png.mcmeta") - if meta_path.is_file(): - logger.debug(f"Loading animation mcmeta: {meta_path}") - # FIXME: hack - try: - meta = AnimationMeta.model_validate_json(meta_path.read_bytes()) - except ValidationError as e: - logger.warning(f"Failed to parse animation meta for {texture_id}:\n{e}") - meta = None - else: - meta = None - - return BlockTextureInfo(path, meta) - def destroy(self): self.window.destroy() diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index ffa74664..35fd21b0 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -51,7 +51,11 @@ def frame_height(self): return self.image.width @cached_property - def frame_count(self): + def _frame_count(self): + """Number of sub-images within `self.image`. + + Not necessarily equal to `len(self.frames)`! + """ count = self.image.height / self.frame_height if not count.is_integer() or count < 1: raise ValueError( @@ -61,10 +65,13 @@ def frame_count(self): ) return int(count) - def get_frame(self, tick: int): + def get_frame_index(self, tick: int): if tick < 0: raise ValueError(f"Expected tick >= 0, got {tick}") - return self.frames[tick % len(self.frames)] + return tick % len(self.frames) + + def get_frame(self, tick: int): + return self.frames[self.get_frame_index(tick)] @cached_property @listify @@ -81,7 +88,7 @@ def frames(self): frames = self.animation.frames or [ AnimationFrame(index=i, time=self.animation.frametime) - for i in range(self.frame_count) + for i in range(self._frame_count) ] frame_images = [(frame, self._get_frame_image(frame)) for frame in frames] @@ -97,9 +104,9 @@ def frames(self): yield image def _get_frame_image(self, frame: AnimationFrame): - if frame.index >= self.frame_count: + if frame.index >= self._frame_count: raise ValueError( - f"Invalid frame index (expected <{self.frame_count}): {frame}" + f"Invalid frame index (expected <{self._frame_count}): {frame}" ) start_y = self.frame_height * frame.index end_y = start_y + self.frame_height diff --git a/src/hexdoc/graphics/utils.py b/src/hexdoc/graphics/utils.py index b05293a8..4abff0c9 100644 --- a/src/hexdoc/graphics/utils.py +++ b/src/hexdoc/graphics/utils.py @@ -7,11 +7,9 @@ import importlib_resources as resources import numpy as np -from PIL.Image import Image from pyrr import Matrix44 from hexdoc.graphics import glsl -from hexdoc.minecraft.model import Animation, AnimationMeta from hexdoc.utils.types import Vec3 @@ -37,22 +35,3 @@ def get_rotation_matrix(eulers: Vec3) -> Matrix44: * Matrix44.from_y_rotation(-eulers[1], "f4") * Matrix44.from_z_rotation(-eulers[2], "f4"), ) - - -# TODO: remove -def get_height_and_layers(image: Image, meta: AnimationMeta | None): - match meta: - case AnimationMeta( - animation=Animation(height=frame_height), - ) if frame_height: - # animated with specified size - layers = image.height // frame_height - case AnimationMeta(): - # size is unspecified, assume it's square and verify later - frame_height = image.width - layers = image.height // frame_height - case None: - # non-animated - frame_height = image.height - layers = 1 - return frame_height, layers From faf7c7e5e94f3778f516efcdb15a8820b71161ae Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 00:25:00 -0400 Subject: [PATCH 009/106] Fix output directory creation --- src/hexdoc/graphics/renderer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index 15c2d04f..f8f1b86c 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -65,7 +65,7 @@ def render_model( else: frames = self._render_block(model) - output_path.mkdir(parents=True, exist_ok=True) + output_path.parent.mkdir(parents=True, exist_ok=True) match frames: case [image]: image.save(output_path) From fdef38b0069c553890a5acabe214ad048565ac20 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 01:00:50 -0400 Subject: [PATCH 010/106] Add progress bar to texture generation --- pyproject.toml | 1 + src/hexdoc/cli/utils/load.py | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index cd17e713..7d29a49a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,7 @@ dependencies = [ "pygithub~=2.1", "pyjson5~=1.6", "requests~=2.31", + "tqdm~=4.66", "typer~=0.12", "typing_extensions~=4.6", "yarl~=1.9", diff --git a/src/hexdoc/cli/utils/load.py b/src/hexdoc/cli/utils/load.py index 69d68502..9429d1d0 100644 --- a/src/hexdoc/cli/utils/load.py +++ b/src/hexdoc/cli/utils/load.py @@ -3,6 +3,8 @@ from textwrap import indent from typing import Any, Literal, overload +from tqdm import tqdm + from hexdoc.core import ( MinecraftVersion, ModResourceLoader, @@ -86,9 +88,9 @@ def render_textures_and_export_metadata( internal_lookups = TextureLookups[Texture](dict) if loader.props.textures.enabled: logger.info(f"Loading and rendering textures to {asset_loader.render_dir}.") - for id, texture in asset_loader.load_and_render_internal_textures( - image_textures - ): + bar = tqdm(asset_loader.load_and_render_internal_textures(image_textures)) + for id, texture in bar: + bar.set_postfix_str(str(id)) texture.insert_texture(internal_lookups, id) # this mod's metadata From e4f33845f0274877ed21500c3a456c35df979a9c Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 01:33:40 -0400 Subject: [PATCH 011/106] Fix logging in tqdm bar --- src/hexdoc/cli/utils/load.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hexdoc/cli/utils/load.py b/src/hexdoc/cli/utils/load.py index 9429d1d0..512a67d3 100644 --- a/src/hexdoc/cli/utils/load.py +++ b/src/hexdoc/cli/utils/load.py @@ -4,6 +4,7 @@ from typing import Any, Literal, overload from tqdm import tqdm +from tqdm.contrib.logging import logging_redirect_tqdm from hexdoc.core import ( MinecraftVersion, @@ -88,10 +89,11 @@ def render_textures_and_export_metadata( internal_lookups = TextureLookups[Texture](dict) if loader.props.textures.enabled: logger.info(f"Loading and rendering textures to {asset_loader.render_dir}.") - bar = tqdm(asset_loader.load_and_render_internal_textures(image_textures)) - for id, texture in bar: - bar.set_postfix_str(str(id)) - texture.insert_texture(internal_lookups, id) + with logging_redirect_tqdm(): + bar = tqdm(asset_loader.load_and_render_internal_textures(image_textures)) + for id, texture in bar: + bar.set_postfix_str(str(id)) + texture.insert_texture(internal_lookups, id) # this mod's metadata metadata = HexdocMetadata( From 08e23e146f71aae36bbed07a1dc66a9395aca53a Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 01:34:04 -0400 Subject: [PATCH 012/106] Implement animation length limit because of woke prismarine --- src/hexdoc/graphics/texture.py | 48 +++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index 35fd21b0..afba5a8d 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -1,8 +1,11 @@ +from __future__ import annotations + import logging from dataclasses import dataclass from functools import cached_property from pathlib import Path +import numpy as np from PIL import Image from pydantic import ValidationError @@ -13,20 +16,34 @@ logger = logging.getLogger(__name__) +MAX_DURATION_SECONDS = 30 +MAX_FRAMES = MAX_DURATION_SECONDS * 20 + +_TEXTURE_CACHE: dict[ResourceLocation, ModelTexture] = {} + + @dataclass(kw_only=True) class ModelTexture: + texture_id: ResourceLocation image: Image.Image animation: Animation | None layer_index: int = -1 @classmethod def load(cls, loader: ModResourceLoader, texture_id: ResourceLocation): + if cached := _TEXTURE_CACHE.get(texture_id): + return cached + logger.debug(f"Loading texture: {texture_id}") _, path = loader.find_resource("assets", "textures", texture_id + ".png") - return cls( + + texture = cls( + texture_id=texture_id, image=Image.open(path).convert("RGBA"), animation=cls._load_animation(path.with_suffix(".png.mcmeta")), ) + _TEXTURE_CACHE[texture_id] = texture + return texture @classmethod def _load_animation(cls, path: Path): @@ -91,17 +108,28 @@ def frames(self): for i in range(self._frame_count) ] - frame_images = [(frame, self._get_frame_image(frame)) for frame in frames] + frame_lerps = [ + (frame, i / frame.time if self.animation.interpolate else 0) + for frame in frames + for i in range(frame.time) + ] + + if (n := len(frame_lerps)) > MAX_FRAMES: + logger.warning( + f"Animation for texture {self.texture_id} is too long, dropping" + + f" {n - MAX_FRAMES} frames ({n} > {MAX_FRAMES})" + ) + idx = np.round(np.linspace(0, n - 1, MAX_FRAMES)).astype(int) + frame_lerps = np.array(frame_lerps)[idx] - for i, (frame, image) in enumerate(frame_images): - # wrap around so it interpolates back to the start of the loop - _, next_image = frame_images[(i + 1) % len(frame_images)] + frame_images = [self._get_frame_image(frame) for frame, _ in frame_lerps] - for i in range(frame.time): - if self.animation.interpolate: - yield Image.blend(image, next_image, i / frame.time) - else: - yield image + for (_, lerp), image, next_image in zip( + frame_lerps, + frame_images, + frame_images[1:] + [frame_images[0]], + ): + yield Image.blend(image, next_image, lerp) def _get_frame_image(self, frame: AnimationFrame): if frame.index >= self._frame_count: From 421c94a2596b1053862967eaca0dc619a9ff843f Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 02:01:39 -0400 Subject: [PATCH 013/106] Change method of frame dropping to hopefully make less choppy animations --- src/hexdoc/graphics/texture.py | 40 +++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index afba5a8d..adfb3b22 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -1,6 +1,7 @@ from __future__ import annotations import logging +import math from dataclasses import dataclass from functools import cached_property from pathlib import Path @@ -108,28 +109,31 @@ def frames(self): for i in range(self._frame_count) ] - frame_lerps = [ - (frame, i / frame.time if self.animation.interpolate else 0) - for frame in frames - for i in range(frame.time) - ] + images = [self._get_frame_image(frame) for frame in frames] - if (n := len(frame_lerps)) > MAX_FRAMES: + frame_time_multiplier = 1 + total_frames = sum(frame.time for frame in frames) + if total_frames > MAX_FRAMES: logger.warning( - f"Animation for texture {self.texture_id} is too long, dropping" - + f" {n - MAX_FRAMES} frames ({n} > {MAX_FRAMES})" + f"Animation for texture {self.texture_id} is too long, dropping about" + + f" {total_frames - MAX_FRAMES} frames" + + f" ({total_frames} > {MAX_FRAMES})" ) - idx = np.round(np.linspace(0, n - 1, MAX_FRAMES)).astype(int) - frame_lerps = np.array(frame_lerps)[idx] - - frame_images = [self._get_frame_image(frame) for frame, _ in frame_lerps] + frame_time_multiplier = MAX_FRAMES / total_frames + + frame_lerps: list[tuple[int, float]] = [ + (frame_idx, time / frame.time if self.animation.interpolate else 0) + for frame_idx, frame in enumerate(frames) + for time in np.linspace( + 0, + frame.time - 1, + max(1, math.floor(frame.time * frame_time_multiplier)), + ) + ] - for (_, lerp), image, next_image in zip( - frame_lerps, - frame_images, - frame_images[1:] + [frame_images[0]], - ): - yield Image.blend(image, next_image, lerp) + for i, lerp in frame_lerps: + j = (i + 1) % len(images) + yield Image.blend(images[i], images[j], lerp) def _get_frame_image(self, frame: AnimationFrame): if frame.index >= self._frame_count: From 6015a5081ad225a1d64b48b54cc7224e88467fa1 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 02:03:30 -0400 Subject: [PATCH 014/106] Temporarily switch from GIF to APNG --- src/hexdoc/graphics/renderer.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index f8f1b86c..ce4953bf 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -70,14 +70,16 @@ def render_model( case [image]: image.save(output_path) case [first, *rest]: - output_path = output_path.with_suffix(".gif") + # TODO: decide if we want to use APNG or GIF + # output_path = output_path.with_suffix(".gif") first.save( output_path, save_all=True, append_images=rest, loop=0, # loop forever duration=1000 / 20, - disposal=2, # restore to background color + # disposal=2, # restore to background color + disposal=1, ) case _: # TODO: awful error message. From b0d8f77d928ba1aa1d7f4501779615fc101ae8f0 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 5 May 2024 02:12:08 -0400 Subject: [PATCH 015/106] Shorten max animation length from 30 to 15 seconds --- src/hexdoc/graphics/texture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index adfb3b22..b824ed89 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -17,7 +17,7 @@ logger = logging.getLogger(__name__) -MAX_DURATION_SECONDS = 30 +MAX_DURATION_SECONDS = 15 MAX_FRAMES = MAX_DURATION_SECONDS * 20 _TEXTURE_CACHE: dict[ResourceLocation, ModelTexture] = {} From 99464506f8b1c7ccacb4ea4d428c0afade29f2f5 Mon Sep 17 00:00:00 2001 From: object-Object Date: Mon, 6 May 2024 15:13:18 -0400 Subject: [PATCH 016/106] Update submodules --- submodules/HexMod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/submodules/HexMod b/submodules/HexMod index 36780a20..29b18478 160000 --- a/submodules/HexMod +++ b/submodules/HexMod @@ -1 +1 @@ -Subproject commit 36780a203afc9bb619d187169d39c0088682f700 +Subproject commit 29b18478ac467da6eafd885baabf675330f52600 From 0ed382b3e541b2e73f7e3d43a3d2e33cb97364d9 Mon Sep 17 00:00:00 2001 From: object-Object Date: Mon, 6 May 2024 15:15:33 -0400 Subject: [PATCH 017/106] Reorder classes in core.properties --- src/hexdoc/core/properties.py | 239 +++++++++++++++++----------------- 1 file changed, 120 insertions(+), 119 deletions(-) diff --git a/src/hexdoc/core/properties.py b/src/hexdoc/core/properties.py index 01fa757f..10021769 100644 --- a/src/hexdoc/core/properties.py +++ b/src/hexdoc/core/properties.py @@ -39,6 +39,47 @@ } +# TODO: why is this a separate class? +class BaseProperties(StripHiddenModel, ValidationContext): + env: SkipJsonSchema[EnvironmentVariableProps] + props_dir: SkipJsonSchema[Path] + + @classmethod + def load(cls, path: Path) -> Self: + return cls.load_data( + props_dir=path.parent, + data=load_toml_with_placeholders(path), + ) + + @classmethod + def load_data(cls, props_dir: Path, data: dict[str, Any]) -> Self: + props_dir = props_dir.resolve() + + with relative_path_root(props_dir): + env = EnvironmentVariableProps.model_getenv() + props = cls.model_validate( + data + | { + "env": env, + "props_dir": props_dir, + }, + ) + + logger.log(TRACE, props) + return props + + @override + @classmethod + def model_json_schema( + cls, + by_alias: bool = True, + ref_template: str = DEFAULT_REF_TEMPLATE, + schema_generator: type[GenerateJsonSchema] = GenerateJsonSchemaTOML, + mode: Literal["validation", "serialization"] = "validation", + ) -> dict[str, Any]: + return super().model_json_schema(by_alias, ref_template, schema_generator, mode) + + class EnvironmentVariableProps(HexdocSettings): # default Actions environment variables github_repository: str @@ -85,6 +126,85 @@ def _append_subdirectory(self) -> Self: return self +class Properties(BaseProperties): + """Pydantic model for `hexdoc.toml` / `properties.toml`.""" + + modid: str + + book_type: str = "patchouli" + """Modid of the `hexdoc.plugin.BookPlugin` to use when loading this book.""" + + # TODO: make another properties type without book_id + book_id: ResourceLocation | None = Field(alias="book", default=None) + extra_books: list[ResourceLocation] = Field(default_factory=list) + + default_lang: str = "en_us" + default_branch: str = "main" + + is_0_black: bool = False + """If true, the style `$(0)` changes the text color to black; otherwise it resets + the text color to the default.""" + + resource_dirs: Sequence[ResourceDir] + export_dir: RelativePath | None = None + + entry_id_blacklist: set[ResourceLocation] = Field(default_factory=set) + + macros: dict[str, str] = Field(default_factory=dict) + link_overrides: dict[str, str] = Field(default_factory=dict) + + textures: TexturesProps = Field(default_factory=lambda: TexturesProps()) + + template: TemplateProps | None = None + + lang: defaultdict[ + str, + Annotated[LangProps, Field(default_factory=lambda: LangProps())], + ] = Field(default_factory=lambda: defaultdict(LangProps)) + """Per-language configuration. The key should be the language code, eg. `en_us`.""" + + extra: dict[str, Any] = Field(default_factory=dict) + + def mod_loc(self, path: str) -> ResourceLocation: + """Returns a ResourceLocation with self.modid as the namespace.""" + return ResourceLocation(self.modid, path) + + @property + def prerender_dir(self): + return self.cache_dir / "prerender" + + @property + def cache_dir(self): + return self.repo_root / ".hexdoc" + + @cached_property + def repo_root(self): + return git_root(self.props_dir) + + +class TexturesProps(StripHiddenModel): + enabled: bool = True + """Set to False to disable texture rendering.""" + strict: bool = True + """Set to False to print some errors instead of throwing them.""" + missing: set[ResourceLocation] | Literal["*"] = Field(default_factory=set) + override: dict[ + ResourceLocation, + PNGTextureOverride | TextureTextureOverride, + ] = Field(default_factory=dict) + + +# TODO: support item/block override +class PNGTextureOverride(StripHiddenModel): + url: PydanticURL + pixelated: bool + + +class TextureTextureOverride(StripHiddenModel): + texture: ResourceLocation + """The id of an image texture (eg. `minecraft:textures/item/stick.png`).""" + + class TemplateProps(StripHiddenModel, validate_assignment=True): static_dir: RelativePath | None = None icon: RelativePath | None = None @@ -126,29 +246,6 @@ def _set_default_render_from(self): return self -# TODO: support item/block override -class PNGTextureOverride(StripHiddenModel): - url: PydanticURL - pixelated: bool - - -class TextureTextureOverride(StripHiddenModel): - texture: ResourceLocation - """The id of an image texture (eg. `minecraft:textures/item/stick.png`).""" - - -class TexturesProps(StripHiddenModel): - enabled: bool = True - """Set to False to disable texture rendering.""" - strict: bool = True - """Set to False to print some errors instead of throwing them.""" - missing: set[ResourceLocation] | Literal["*"] = Field(default_factory=set) - override: dict[ - ResourceLocation, - PNGTextureOverride | TextureTextureOverride, - ] = Field(default_factory=dict) - - class LangProps(StripHiddenModel): """Configuration for a specific book language.""" @@ -162,99 +259,3 @@ class LangProps(StripHiddenModel): Using this option for the default language is not recommended. """ - - -class BaseProperties(StripHiddenModel, ValidationContext): - env: SkipJsonSchema[EnvironmentVariableProps] - props_dir: SkipJsonSchema[Path] - - @classmethod - def load(cls, path: Path) -> Self: - return cls.load_data( - props_dir=path.parent, - data=load_toml_with_placeholders(path), - ) - - @classmethod - def load_data(cls, props_dir: Path, data: dict[str, Any]) -> Self: - props_dir = props_dir.resolve() - - with relative_path_root(props_dir): - env = EnvironmentVariableProps.model_getenv() - props = cls.model_validate( - data - | { - "env": env, - "props_dir": props_dir, - }, - ) - - logger.log(TRACE, props) - return props - - @override - @classmethod - def model_json_schema( - cls, - by_alias: bool = True, - ref_template: str = DEFAULT_REF_TEMPLATE, - schema_generator: type[GenerateJsonSchema] = GenerateJsonSchemaTOML, - mode: Literal["validation", "serialization"] = "validation", - ) -> dict[str, Any]: - return super().model_json_schema(by_alias, ref_template, schema_generator, mode) - - -class Properties(BaseProperties): - """Pydantic model for `hexdoc.toml` / `properties.toml`.""" - - modid: str - - book_type: str = "patchouli" - """Modid of the `hexdoc.plugin.BookPlugin` to use when loading this book.""" - - # TODO: make another properties type without book_id - book_id: ResourceLocation | None = Field(alias="book", default=None) - extra_books: list[ResourceLocation] = Field(default_factory=list) - - default_lang: str = "en_us" - default_branch: str = "main" - - is_0_black: bool = False - """If true, the style `$(0)` changes the text color to black; otherwise it resets - the text color to the default.""" - - resource_dirs: Sequence[ResourceDir] - export_dir: RelativePath | None = None - - entry_id_blacklist: set[ResourceLocation] = Field(default_factory=set) - - macros: dict[str, str] = Field(default_factory=dict) - link_overrides: dict[str, str] = Field(default_factory=dict) - - textures: TexturesProps = Field(default_factory=TexturesProps) - - template: TemplateProps | None = None - - lang: defaultdict[ - str, - Annotated[LangProps, Field(default_factory=LangProps)], - ] = Field(default_factory=lambda: defaultdict(LangProps)) - """Per-language configuration. The key should be the language code, eg. `en_us`.""" - - extra: dict[str, Any] = Field(default_factory=dict) - - def mod_loc(self, path: str) -> ResourceLocation: - """Returns a ResourceLocation with self.modid as the namespace.""" - return ResourceLocation(self.modid, path) - - @property - def prerender_dir(self): - return self.cache_dir / "prerender" - - @property - def cache_dir(self): - return self.repo_root / ".hexdoc" - - @cached_property - def repo_root(self): - return git_root(self.props_dir) From 111d599ee59521d404d6174a6c85db57d2e56775 Mon Sep 17 00:00:00 2001 From: object-Object Date: Mon, 6 May 2024 15:55:41 -0400 Subject: [PATCH 018/106] Add section in hexdoc.toml for configuring animated textures --- src/hexdoc/core/properties.py | 31 +++++++++++++++++++ src/hexdoc/graphics/renderer.py | 54 +++++++++++++++++++++------------ src/hexdoc/graphics/texture.py | 18 ++++++----- 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/src/hexdoc/core/properties.py b/src/hexdoc/core/properties.py index 10021769..b3940396 100644 --- a/src/hexdoc/core/properties.py +++ b/src/hexdoc/core/properties.py @@ -187,12 +187,17 @@ class TexturesProps(StripHiddenModel): """Set to False to disable texture rendering.""" strict: bool = True """Set to False to print some errors instead of throwing them.""" + missing: set[ResourceLocation] | Literal["*"] = Field(default_factory=set) override: dict[ ResourceLocation, PNGTextureOverride | TextureTextureOverride, ] = Field(default_factory=dict) + animated: AnimatedTexturesProps = Field( + default_factory=lambda: AnimatedTexturesProps(), + ) + # TODO: support item/block override class PNGTextureOverride(StripHiddenModel): @@ -205,6 +210,32 @@ class TextureTextureOverride(StripHiddenModel): """The id of an image texture (eg. `minecraft:textures/item/stick.png`).""" +class AnimatedTexturesProps(StripHiddenModel): + enabled: bool = True + """If set to `False`, animated textures will be rendered as a PNG with the first + frame of the animation.""" + format: Literal["apng", "gif"] = "apng" + """Animated image output format. + + APNG (the default) is higher quality, but the file size is a bit larger. + + GIF produces smaller but lower quality files, and interpolated textures may have + issues with flickering. + """ + max_frames: Annotated[int, Field(ge=0)] = 15 * 20 # 15 seconds * 20 tps + """Maximum number of frames for animated textures (1 frame = 1 tick = 1/20 seconds). + If a texture would have more frames than this, some frames will be dropped. + + This is mostly necessary because of prismarine, which is an interpolated texture + with a total length of 6600 frames or 5.5 minutes. + + The default value is 300 frames or 15 seconds, producing about a 3 MB animation for + prismarine. + + To disable the frame limit entirely, set this value to 0. + """ + + class TemplateProps(StripHiddenModel, validate_assignment=True): static_dir: RelativePath | None = None icon: RelativePath | None = None diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index ce4953bf..b44a670d 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -11,6 +11,7 @@ from moderngl_window.context.headless import Window as HeadlessWindow from PIL import Image from PIL.Image import Resampling +from PIL.PngImagePlugin import Disposal as APNGDisposal from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.graphics.texture import ModelTexture @@ -56,36 +57,25 @@ def render_model( model.resolve(self.loader) - output_path = Path(output_path) - if self.output_dir and not output_path.is_absolute(): - output_path = self.output_dir / output_path - if model.is_generated_item: frames = self._render_item(model) else: frames = self._render_block(model) + output_path = Path(output_path) + if self.output_dir and not output_path.is_absolute(): + output_path = self.output_dir / output_path output_path.parent.mkdir(parents=True, exist_ok=True) + match frames: + case []: + # TODO: awful error message. + raise ValueError("No frames rendered!") case [image]: image.save(output_path) - case [first, *rest]: - # TODO: decide if we want to use APNG or GIF - # output_path = output_path.with_suffix(".gif") - first.save( - output_path, - save_all=True, - append_images=rest, - loop=0, # loop forever - duration=1000 / 20, - # disposal=2, # restore to background color - disposal=1, - ) + return output_path.suffix case _: - # TODO: awful error message. - raise ValueError("No frames rendered!") - - return output_path.suffix + return self._save_animation(output_path, frames) def _render_block(self, model: BlockModel): textures = { @@ -135,6 +125,30 @@ def _load_layers(self, model: BlockModel): texture.layer_index = int(index) yield texture + def _save_animation(self, output_path: Path, frames: list[Image.Image]): + kwargs: dict[str, Any] + match self.loader.props.textures.animated.format: + case "apng": + suffix = ".png" + kwargs = dict( + disposal=APNGDisposal.OP_BACKGROUND, + ) + case "gif": + suffix = ".gif" + kwargs = dict( + loop=0, # loop forever + disposal=2, # restore to background color + ) + + frames[0].save( + output_path.with_suffix(suffix), + save_all=True, + append_images=frames[1:], + duration=1000 / 20, + **kwargs, + ) + return suffix + def destroy(self): self.window.destroy() diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index b824ed89..9e29125f 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -11,15 +11,13 @@ from pydantic import ValidationError from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.core.properties import AnimatedTexturesProps from hexdoc.minecraft.model import Animation, AnimationFrame, AnimationMeta from hexdoc.utils import listify logger = logging.getLogger(__name__) -MAX_DURATION_SECONDS = 15 -MAX_FRAMES = MAX_DURATION_SECONDS * 20 - _TEXTURE_CACHE: dict[ResourceLocation, ModelTexture] = {} @@ -29,6 +27,7 @@ class ModelTexture: image: Image.Image animation: Animation | None layer_index: int = -1 + props: AnimatedTexturesProps @classmethod def load(cls, loader: ModResourceLoader, texture_id: ResourceLocation): @@ -42,6 +41,7 @@ def load(cls, loader: ModResourceLoader, texture_id: ResourceLocation): texture_id=texture_id, image=Image.open(path).convert("RGBA"), animation=cls._load_animation(path.with_suffix(".png.mcmeta")), + props=loader.props.textures.animated, ) _TEXTURE_CACHE[texture_id] = texture return texture @@ -109,17 +109,21 @@ def frames(self): for i in range(self._frame_count) ] + if not self.props.enabled: + yield self._get_frame_image(frames[0]) + return + images = [self._get_frame_image(frame) for frame in frames] frame_time_multiplier = 1 total_frames = sum(frame.time for frame in frames) - if total_frames > MAX_FRAMES: + if self.props.max_frames > 0 and total_frames > self.props.max_frames: logger.warning( f"Animation for texture {self.texture_id} is too long, dropping about" - + f" {total_frames - MAX_FRAMES} frames" - + f" ({total_frames} > {MAX_FRAMES})" + + f" {total_frames - self.props.max_frames} frames" + + f" ({total_frames} > {self.props.max_frames})" ) - frame_time_multiplier = MAX_FRAMES / total_frames + frame_time_multiplier = self.props.max_frames / total_frames frame_lerps: list[tuple[int, float]] = [ (frame_idx, time / frame.time if self.animation.interpolate else 0) From 3fe67231db282dcde8b48c86f09d98217e4602e3 Mon Sep 17 00:00:00 2001 From: object-Object Date: Mon, 6 May 2024 16:13:57 -0400 Subject: [PATCH 019/106] Implement props.textures.large_items, use an enum for animation formats --- src/hexdoc/cli/app.py | 5 +++++ src/hexdoc/core/properties.py | 16 +++++++++++++--- src/hexdoc/graphics/renderer.py | 16 ++++++++++++---- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 9d997374..7c5a7a2a 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -16,6 +16,7 @@ from hexdoc.__version__ import VERSION from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.core.properties import AnimationFormat from hexdoc.data.metadata import HexdocMetadata from hexdoc.data.sitemap import delete_updated_books, dump_sitemap, load_sitemap from hexdoc.graphics import DebugType, ModelRenderer @@ -439,6 +440,7 @@ def render_model( axes: bool = False, normals: bool = False, size: Optional[int] = None, + format: Optional[AnimationFormat] = None, ): """Use hexdoc's block rendering to render an item or block model.""" set_default_env() @@ -450,6 +452,9 @@ def render_model( if normals: debug |= DebugType.NORMALS + if format: + props.textures.animated.format = format + with ( ModResourceLoader.load_all(props, pm, export=False) as loader, ModelRenderer( diff --git a/src/hexdoc/core/properties.py b/src/hexdoc/core/properties.py index b3940396..e4f299f1 100644 --- a/src/hexdoc/core/properties.py +++ b/src/hexdoc/core/properties.py @@ -2,6 +2,7 @@ import logging from collections import defaultdict +from enum import StrEnum from functools import cached_property from pathlib import Path from typing import Annotated, Any, Literal, Self, Sequence @@ -194,6 +195,10 @@ class TexturesProps(StripHiddenModel): PNGTextureOverride | TextureTextureOverride, ] = Field(default_factory=dict) + large_items: bool = True + """Controls whether flat item renders should be enlarged after rendering, or left at + the default size (usually 16x16). Defaults to `True`.""" + animated: AnimatedTexturesProps = Field( default_factory=lambda: AnimatedTexturesProps(), ) @@ -210,16 +215,21 @@ class TextureTextureOverride(StripHiddenModel): """The id of an image texture (eg. `minecraft:textures/item/stick.png`).""" +class AnimationFormat(StrEnum): + APNG = "apng" + GIF = "gif" + + class AnimatedTexturesProps(StripHiddenModel): enabled: bool = True """If set to `False`, animated textures will be rendered as a PNG with the first frame of the animation.""" - format: Literal["apng", "gif"] = "apng" + format: AnimationFormat = AnimationFormat.APNG """Animated image output format. - APNG (the default) is higher quality, but the file size is a bit larger. + `apng` (the default) is higher quality, but the file size is a bit larger. - GIF produces smaller but lower quality files, and interpolated textures may have + `gif` produces smaller but lower quality files, and interpolated textures may have issues with flickering. """ max_frames: Annotated[int, Field(ge=0)] = 15 * 20 # 15 seconds * 20 tps diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index b44a670d..54214408 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -14,10 +14,11 @@ from PIL.PngImagePlugin import Disposal as APNGDisposal from hexdoc.core import ModResourceLoader, ResourceLocation -from hexdoc.graphics.texture import ModelTexture +from hexdoc.core.properties import AnimationFormat from hexdoc.minecraft.model import BlockModel from .block import BlockRenderer +from .texture import ModelTexture from .utils import DebugType logger = logging.getLogger(__name__) @@ -43,6 +44,13 @@ def __post_init__(self): self.window.swap_buffers() self.window.set_default_viewport() + if self.texture_props.large_items: + self.item_size = self.item_size or 256 + + @property + def texture_props(self): + return self.loader.props.textures + @property def ctx(self): return self.window.ctx @@ -127,13 +135,13 @@ def _load_layers(self, model: BlockModel): def _save_animation(self, output_path: Path, frames: list[Image.Image]): kwargs: dict[str, Any] - match self.loader.props.textures.animated.format: - case "apng": + match self.texture_props.animated.format: + case AnimationFormat.APNG: suffix = ".png" kwargs = dict( disposal=APNGDisposal.OP_BACKGROUND, ) - case "gif": + case AnimationFormat.GIF: suffix = ".gif" kwargs = dict( loop=0, # loop forever From a08886d6f6f1cb4cb4dee73c3d79df1ef738f4e8 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 8 May 2024 12:50:22 -0400 Subject: [PATCH 020/106] Set default env for all commands if not in CI --- src/hexdoc/cli/app.py | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 7c5a7a2a..e08f2c0d 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -49,16 +49,6 @@ logger = logging.getLogger(__name__) -def set_default_env(): - """Sets placeholder values for unneeded environment variables.""" - for key, value in { - "GITHUB_REPOSITORY": "placeholder/placeholder", - "GITHUB_SHA": "", - "GITHUB_PAGES_URL": "", - }.items(): - os.environ.setdefault(key, value) - - @dataclass(kw_only=True) class LoadedBookInfo: language: str @@ -87,11 +77,27 @@ def callback( Option("--version", "-V", callback=version_callback, is_eager=True), ] = False, ): + setup_logging(verbosity, ci=False, quiet_langs=quiet_lang) + if quiet_lang: logger.warning( "`--quiet-lang` is deprecated, use `props.lang.{lang}.quiet` instead." ) - setup_logging(verbosity, ci=False, quiet_langs=quiet_lang) + + if not os.getenv("CI"): + set_any = False + for key, value in { + "GITHUB_REPOSITORY": "placeholder/placeholder", + "GITHUB_SHA": "00000000", + "GITHUB_PAGES_URL": "https://example.hexxy.media", + }.items(): + if not os.getenv(key): + os.environ[key] = value + set_any = True + if set_any: + logger.info( + "CI not detected, setting defaults for missing environment variables." + ) @app.command() @@ -443,7 +449,6 @@ def render_model( format: Optional[AnimationFormat] = None, ): """Use hexdoc's block rendering to render an item or block model.""" - set_default_env() props, pm, *_ = load_common_data(props_file, branch="") debug = DebugType.NONE @@ -482,7 +487,6 @@ def render_models( site_url = URL(site_url_str or "") - set_default_env() props, pm, _, plugin = load_common_data(props_file, branch="") with ModResourceLoader.load_all(props, pm, export=export_resources) as loader: From a6203e7954b86a8d4485d10b6880d1cd9f070a27 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 8 May 2024 19:32:22 -0400 Subject: [PATCH 021/106] Allow using --no-install with docusaurus session --- noxfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/noxfile.py b/noxfile.py index a644c5cf..dc6ca088 100644 --- a/noxfile.py +++ b/noxfile.py @@ -174,7 +174,8 @@ def pdoc(session: nox.Session): # docs for the docs! -@nox.session(tags=["docs"], python=False) +# note: we can't use python=False because then --no-install doesn't work +@nox.session(tags=["docs"]) def docusaurus(session: nox.Session): shutil.copytree("media", f"{STATIC_GENERATED}/img", dirs_exist_ok=True) From 8ba7d615a081fe3889fcdf460899aea475505ed9 Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 9 May 2024 15:18:39 -0400 Subject: [PATCH 022/106] Implement static:// URL scheme for linking to static pages without opening a new tab --- .../docs/03-guides/01-configuration.md | 6 + .../docs/03-guides/02-custom-styles.md | 4 +- web/docusaurus/docusaurus.config.ts | 2 + web/docusaurus/package-lock.json | 3723 ++++++----------- .../src/remark/internalPathnameLinks.ts | 324 ++ 5 files changed, 1580 insertions(+), 2479 deletions(-) create mode 100644 web/docusaurus/src/remark/internalPathnameLinks.ts diff --git a/web/docusaurus/docs/03-guides/01-configuration.md b/web/docusaurus/docs/03-guides/01-configuration.md index c80cf707..4799eb74 100644 --- a/web/docusaurus/docs/03-guides/01-configuration.md +++ b/web/docusaurus/docs/03-guides/01-configuration.md @@ -11,3 +11,9 @@ With Taplo-based tools like Even Better TOML, you can enable the schema by addin ```toml #:schema https://hexdoc.hexxy.media/schema/core/Properties.json ``` + +## API Docs + +The `hexdoc.toml` file models are included in hexdoc's auto-generated API documentation. + +All relevant classes can be found in the following module: [hexdoc.core.properties](static:///docs/api/hexdoc/core/properties.html) diff --git a/web/docusaurus/docs/03-guides/02-custom-styles.md b/web/docusaurus/docs/03-guides/02-custom-styles.md index 2e27c2e5..3d827a0f 100644 --- a/web/docusaurus/docs/03-guides/02-custom-styles.md +++ b/web/docusaurus/docs/03-guides/02-custom-styles.md @@ -2,7 +2,7 @@ The easiest way to customize the appearance of your web book is by adding styles to `index.css`. -## Using [`template.extend_render`](pathname:///docs/api/hexdoc/core/properties.html#TemplateProps.extend_render) to overwrite `index.css` +## Using [`template.extend_render`](static:///docs/api/hexdoc/core/properties.html#TemplateProps.extend_render) to overwrite `index.css` Create a template called `yourmodid.css.jinja`: @@ -61,7 +61,7 @@ There are two problems with this approach: * You must specify a namespace (the `hexdoc:` part) to prevent the template from recursively rendering itself. This can be error-prone if you pick the wrong namespace. * For example, [hexdoc-hexcasting](https://github.com/object-Object/HexMod/blob/7edab68db2bee50285e354f7c9b935b512ebc4bd/doc/src/hexdoc_hexcasting/_templates/index.css.jinja) adds styles to `index.css`, which is why the above note is necessary. -* Your custom styles might interfere with other hexdoc plugins if they add your modid to [`template.include`](pathname:///docs/api/hexdoc/core/properties.html#TemplateProps.include). +* Your custom styles might interfere with other hexdoc plugins if they add your modid to [`template.include`](static:///docs/api/hexdoc/core/properties.html#TemplateProps.include). Both of these problems can be avoided by using the `template.extend_render` approach. diff --git a/web/docusaurus/docusaurus.config.ts b/web/docusaurus/docusaurus.config.ts index ff53ec23..acd84eb3 100644 --- a/web/docusaurus/docusaurus.config.ts +++ b/web/docusaurus/docusaurus.config.ts @@ -1,6 +1,7 @@ import { themes as prismThemes } from "prism-react-renderer"; import type { Config } from "@docusaurus/types"; import type * as Preset from "@docusaurus/preset-classic"; +import internalPathnameLinks from "./src/remark/internalPathnameLinks"; const SITE_URL = "https://hexdoc.hexxy.media"; @@ -40,6 +41,7 @@ const config: Config = { keywords: ["hex-casting"], extendDefaults: true, }, + beforeDefaultRemarkPlugins: [internalPathnameLinks], }, blog: false, theme: { diff --git a/web/docusaurus/package-lock.json b/web/docusaurus/package-lock.json index 69cdcab2..4007821b 100644 --- a/web/docusaurus/package-lock.json +++ b/web/docusaurus/package-lock.json @@ -28,8 +28,7 @@ }, "node_modules/@algolia/autocomplete-core": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz", - "integrity": "sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==", + "license": "MIT", "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.9.3", "@algolia/autocomplete-shared": "1.9.3" @@ -37,8 +36,7 @@ }, "node_modules/@algolia/autocomplete-plugin-algolia-insights": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-plugin-algolia-insights/-/autocomplete-plugin-algolia-insights-1.9.3.tgz", - "integrity": "sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==", + "license": "MIT", "dependencies": { "@algolia/autocomplete-shared": "1.9.3" }, @@ -48,8 +46,7 @@ }, "node_modules/@algolia/autocomplete-preset-algolia": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-preset-algolia/-/autocomplete-preset-algolia-1.9.3.tgz", - "integrity": "sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==", + "license": "MIT", "dependencies": { "@algolia/autocomplete-shared": "1.9.3" }, @@ -60,8 +57,7 @@ }, "node_modules/@algolia/autocomplete-shared": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/@algolia/autocomplete-shared/-/autocomplete-shared-1.9.3.tgz", - "integrity": "sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==", + "license": "MIT", "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" @@ -69,29 +65,25 @@ }, "node_modules/@algolia/cache-browser-local-storage": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-browser-local-storage/-/cache-browser-local-storage-4.22.1.tgz", - "integrity": "sha512-Sw6IAmOCvvP6QNgY9j+Hv09mvkvEIDKjYW8ow0UDDAxSXy664RBNQk3i/0nt7gvceOJ6jGmOTimaZoY1THmU7g==", + "license": "MIT", "dependencies": { "@algolia/cache-common": "4.22.1" } }, "node_modules/@algolia/cache-common": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-common/-/cache-common-4.22.1.tgz", - "integrity": "sha512-TJMBKqZNKYB9TptRRjSUtevJeQVXRmg6rk9qgFKWvOy8jhCPdyNZV1nB3SKGufzvTVbomAukFR8guu/8NRKBTA==" + "license": "MIT" }, "node_modules/@algolia/cache-in-memory": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/cache-in-memory/-/cache-in-memory-4.22.1.tgz", - "integrity": "sha512-ve+6Ac2LhwpufuWavM/aHjLoNz/Z/sYSgNIXsinGofWOysPilQZPUetqLj8vbvi+DHZZaYSEP9H5SRVXnpsNNw==", + "license": "MIT", "dependencies": { "@algolia/cache-common": "4.22.1" } }, "node_modules/@algolia/client-account": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-account/-/client-account-4.22.1.tgz", - "integrity": "sha512-k8m+oegM2zlns/TwZyi4YgCtyToackkOpE+xCaKCYfBfDtdGOaVZCM5YvGPtK+HGaJMIN/DoTL8asbM3NzHonw==", + "license": "MIT", "dependencies": { "@algolia/client-common": "4.22.1", "@algolia/client-search": "4.22.1", @@ -100,8 +92,7 @@ }, "node_modules/@algolia/client-analytics": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-4.22.1.tgz", - "integrity": "sha512-1ssi9pyxyQNN4a7Ji9R50nSdISIumMFDwKNuwZipB6TkauJ8J7ha/uO60sPJFqQyqvvI+px7RSNRQT3Zrvzieg==", + "license": "MIT", "dependencies": { "@algolia/client-common": "4.22.1", "@algolia/client-search": "4.22.1", @@ -111,8 +102,7 @@ }, "node_modules/@algolia/client-common": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-4.22.1.tgz", - "integrity": "sha512-IvaL5v9mZtm4k4QHbBGDmU3wa/mKokmqNBqPj0K7lcR8ZDKzUorhcGp/u8PkPC/e0zoHSTvRh7TRkGX3Lm7iOQ==", + "license": "MIT", "dependencies": { "@algolia/requester-common": "4.22.1", "@algolia/transporter": "4.22.1" @@ -120,8 +110,7 @@ }, "node_modules/@algolia/client-personalization": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-4.22.1.tgz", - "integrity": "sha512-sl+/klQJ93+4yaqZ7ezOttMQ/nczly/3GmgZXJ1xmoewP5jmdP/X/nV5U7EHHH3hCUEHeN7X1nsIhGPVt9E1cQ==", + "license": "MIT", "dependencies": { "@algolia/client-common": "4.22.1", "@algolia/requester-common": "4.22.1", @@ -130,8 +119,7 @@ }, "node_modules/@algolia/client-search": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-4.22.1.tgz", - "integrity": "sha512-yb05NA4tNaOgx3+rOxAmFztgMTtGBi97X7PC3jyNeGiwkAjOZc2QrdZBYyIdcDLoI09N0gjtpClcackoTN0gPA==", + "license": "MIT", "dependencies": { "@algolia/client-common": "4.22.1", "@algolia/requester-common": "4.22.1", @@ -140,47 +128,40 @@ }, "node_modules/@algolia/events": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@algolia/events/-/events-4.0.1.tgz", - "integrity": "sha512-FQzvOCgoFXAbf5Y6mYozw2aj5KCJoA3m4heImceldzPSMbdyS4atVjJzXKMsfX3wnZTFYwkkt8/z8UesLHlSBQ==" + "license": "MIT" }, "node_modules/@algolia/logger-common": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-common/-/logger-common-4.22.1.tgz", - "integrity": "sha512-OnTFymd2odHSO39r4DSWRFETkBufnY2iGUZNrMXpIhF5cmFE8pGoINNPzwg02QLBlGSaLqdKy0bM8S0GyqPLBg==" + "license": "MIT" }, "node_modules/@algolia/logger-console": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/logger-console/-/logger-console-4.22.1.tgz", - "integrity": "sha512-O99rcqpVPKN1RlpgD6H3khUWylU24OXlzkavUAMy6QZd1776QAcauE3oP8CmD43nbaTjBexZj2nGsBH9Tc0FVA==", + "license": "MIT", "dependencies": { "@algolia/logger-common": "4.22.1" } }, "node_modules/@algolia/requester-browser-xhr": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-4.22.1.tgz", - "integrity": "sha512-dtQGYIg6MteqT1Uay3J/0NDqD+UciHy3QgRbk7bNddOJu+p3hzjTRYESqEnoX/DpEkaNYdRHUKNylsqMpgwaEw==", + "license": "MIT", "dependencies": { "@algolia/requester-common": "4.22.1" } }, "node_modules/@algolia/requester-common": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-common/-/requester-common-4.22.1.tgz", - "integrity": "sha512-dgvhSAtg2MJnR+BxrIFqlLtkLlVVhas9HgYKMk2Uxiy5m6/8HZBL40JVAMb2LovoPFs9I/EWIoFVjOrFwzn5Qg==" + "license": "MIT" }, "node_modules/@algolia/requester-node-http": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-4.22.1.tgz", - "integrity": "sha512-JfmZ3MVFQkAU+zug8H3s8rZ6h0ahHZL/SpMaSasTCGYR5EEJsCc8SI5UZ6raPN2tjxa5bxS13BRpGSBUens7EA==", + "license": "MIT", "dependencies": { "@algolia/requester-common": "4.22.1" } }, "node_modules/@algolia/transporter": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/@algolia/transporter/-/transporter-4.22.1.tgz", - "integrity": "sha512-kzWgc2c9IdxMa3YqA6TN0NW5VrKYYW/BELIn7vnLyn+U/RFdZ4lxxt9/8yq3DKV5snvoDzzO4ClyejZRdV3lMQ==", + "license": "MIT", "dependencies": { "@algolia/cache-common": "4.22.1", "@algolia/logger-common": "4.22.1", @@ -189,8 +170,7 @@ }, "node_modules/@ampproject/remapping": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "license": "Apache-2.0", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -201,8 +181,7 @@ }, "node_modules/@babel/code-frame": { "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "license": "MIT", "dependencies": { "@babel/highlight": "^7.23.4", "chalk": "^2.4.2" @@ -213,8 +192,7 @@ }, "node_modules/@babel/code-frame/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -224,8 +202,7 @@ }, "node_modules/@babel/code-frame/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -237,37 +214,32 @@ }, "node_modules/@babel/code-frame/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/code-frame/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "license": "MIT" }, "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/code-frame/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/code-frame/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -277,16 +249,14 @@ }, "node_modules/@babel/compat-data": { "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", - "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz", - "integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==", + "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.23.5", @@ -314,16 +284,14 @@ }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", @@ -336,8 +304,7 @@ }, "node_modules/@babel/helper-annotate-as-pure": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -347,8 +314,7 @@ }, "node_modules/@babel/helper-builder-binary-assignment-operator-visitor": { "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz", - "integrity": "sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.15" }, @@ -358,8 +324,7 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", - "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-validator-option": "^7.23.5", @@ -373,16 +338,14 @@ }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-class-features-plugin": { "version": "7.23.10", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz", - "integrity": "sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", @@ -403,16 +366,14 @@ }, "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-create-regexp-features-plugin": { "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz", - "integrity": "sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "regexpu-core": "^5.3.1", @@ -427,16 +388,14 @@ }, "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/helper-define-polyfill-provider": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz", - "integrity": "sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q==", + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", "@babel/helper-plugin-utils": "^7.22.5", @@ -450,16 +409,14 @@ }, "node_modules/@babel/helper-environment-visitor": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "license": "MIT", "dependencies": { "@babel/template": "^7.22.15", "@babel/types": "^7.23.0" @@ -470,8 +427,7 @@ }, "node_modules/@babel/helper-hoist-variables": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -481,8 +437,7 @@ }, "node_modules/@babel/helper-member-expression-to-functions": { "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz", - "integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==", + "license": "MIT", "dependencies": { "@babel/types": "^7.23.0" }, @@ -492,8 +447,7 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", - "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.15" }, @@ -503,8 +457,7 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", - "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-module-imports": "^7.22.15", @@ -521,8 +474,7 @@ }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz", - "integrity": "sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -532,16 +484,14 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz", - "integrity": "sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-environment-visitor": "^7.22.20", @@ -556,8 +506,7 @@ }, "node_modules/@babel/helper-replace-supers": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz", - "integrity": "sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw==", + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-member-expression-to-functions": "^7.22.15", @@ -572,8 +521,7 @@ }, "node_modules/@babel/helper-simple-access": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -583,8 +531,7 @@ }, "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz", - "integrity": "sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -594,8 +541,7 @@ }, "node_modules/@babel/helper-split-export-declaration": { "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "license": "MIT", "dependencies": { "@babel/types": "^7.22.5" }, @@ -605,32 +551,28 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", - "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-wrap-function": { "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz", - "integrity": "sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw==", + "license": "MIT", "dependencies": { "@babel/helper-function-name": "^7.22.5", "@babel/template": "^7.22.15", @@ -642,8 +584,7 @@ }, "node_modules/@babel/helpers": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz", - "integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==", + "license": "MIT", "dependencies": { "@babel/template": "^7.23.9", "@babel/traverse": "^7.23.9", @@ -655,8 +596,7 @@ }, "node_modules/@babel/highlight": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "license": "MIT", "dependencies": { "@babel/helper-validator-identifier": "^7.22.20", "chalk": "^2.4.2", @@ -668,8 +608,7 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -679,8 +618,7 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -692,37 +630,32 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -732,8 +665,7 @@ }, "node_modules/@babel/parser": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz", - "integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==", + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -743,8 +675,7 @@ }, "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz", - "integrity": "sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -757,8 +688,7 @@ }, "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz", - "integrity": "sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -773,8 +703,7 @@ }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.23.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.7.tgz", - "integrity": "sha512-LlRT7HgaifEpQA1ZgLVOIJZZFVPWN5iReq/7/JixwBtwcoeVGDBD53ZV28rrsLYOZs1Y/EHhA8N/Z6aazHR8cw==", + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5" @@ -788,8 +717,7 @@ }, "node_modules/@babel/plugin-proposal-private-property-in-object": { "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", "engines": { "node": ">=6.9.0" }, @@ -799,8 +727,7 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -810,8 +737,7 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -821,8 +747,7 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -835,8 +760,7 @@ }, "node_modules/@babel/plugin-syntax-dynamic-import": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", - "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -846,8 +770,7 @@ }, "node_modules/@babel/plugin-syntax-export-namespace-from": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz", - "integrity": "sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.3" }, @@ -857,8 +780,7 @@ }, "node_modules/@babel/plugin-syntax-import-assertions": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz", - "integrity": "sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -871,8 +793,7 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz", - "integrity": "sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -885,8 +806,7 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -896,8 +816,7 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -907,8 +826,7 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz", - "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -921,8 +839,7 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -932,8 +849,7 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -943,8 +859,7 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -954,8 +869,7 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -965,8 +879,7 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -976,8 +889,7 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -987,8 +899,7 @@ }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1001,8 +912,7 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -1015,8 +925,7 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz", - "integrity": "sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1029,8 +938,7 @@ }, "node_modules/@babel/plugin-syntax-unicode-sets-regex": { "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.18.6", "@babel/helper-plugin-utils": "^7.18.6" @@ -1044,8 +952,7 @@ }, "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz", - "integrity": "sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1058,8 +965,7 @@ }, "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.9.tgz", - "integrity": "sha512-8Q3veQEDGe14dTYuwagbRtwxQDnytyg1JFu4/HwEMETeofocrB0U0ejBJIXoeG/t2oXZ8kzCyI0ZZfbT80VFNQ==", + "license": "MIT", "dependencies": { "@babel/helper-environment-visitor": "^7.22.20", "@babel/helper-plugin-utils": "^7.22.5", @@ -1075,8 +981,7 @@ }, "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz", - "integrity": "sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", @@ -1091,8 +996,7 @@ }, "node_modules/@babel/plugin-transform-block-scoped-functions": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz", - "integrity": "sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1105,8 +1009,7 @@ }, "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz", - "integrity": "sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1119,8 +1022,7 @@ }, "node_modules/@babel/plugin-transform-class-properties": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz", - "integrity": "sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg==", + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1134,8 +1036,7 @@ }, "node_modules/@babel/plugin-transform-class-static-block": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz", - "integrity": "sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ==", + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", @@ -1150,8 +1051,7 @@ }, "node_modules/@babel/plugin-transform-classes": { "version": "7.23.8", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz", - "integrity": "sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-compilation-targets": "^7.23.6", @@ -1171,8 +1071,7 @@ }, "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz", - "integrity": "sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/template": "^7.22.15" @@ -1186,8 +1085,7 @@ }, "node_modules/@babel/plugin-transform-destructuring": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz", - "integrity": "sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1200,8 +1098,7 @@ }, "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz", - "integrity": "sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ==", + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1215,8 +1112,7 @@ }, "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz", - "integrity": "sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1229,8 +1125,7 @@ }, "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz", - "integrity": "sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-dynamic-import": "^7.8.3" @@ -1244,8 +1139,7 @@ }, "node_modules/@babel/plugin-transform-exponentiation-operator": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz", - "integrity": "sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ==", + "license": "MIT", "dependencies": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1259,8 +1153,7 @@ }, "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz", - "integrity": "sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-export-namespace-from": "^7.8.3" @@ -1274,8 +1167,7 @@ }, "node_modules/@babel/plugin-transform-for-of": { "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz", - "integrity": "sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1289,8 +1181,7 @@ }, "node_modules/@babel/plugin-transform-function-name": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz", - "integrity": "sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw==", + "license": "MIT", "dependencies": { "@babel/helper-compilation-targets": "^7.22.15", "@babel/helper-function-name": "^7.23.0", @@ -1305,8 +1196,7 @@ }, "node_modules/@babel/plugin-transform-json-strings": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz", - "integrity": "sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-json-strings": "^7.8.3" @@ -1320,8 +1210,7 @@ }, "node_modules/@babel/plugin-transform-literals": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz", - "integrity": "sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1334,8 +1223,7 @@ }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz", - "integrity": "sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" @@ -1349,8 +1237,7 @@ }, "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz", - "integrity": "sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1363,8 +1250,7 @@ }, "node_modules/@babel/plugin-transform-modules-amd": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz", - "integrity": "sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw==", + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" @@ -1378,8 +1264,7 @@ }, "node_modules/@babel/plugin-transform-modules-commonjs": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz", - "integrity": "sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA==", + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5", @@ -1394,8 +1279,7 @@ }, "node_modules/@babel/plugin-transform-modules-systemjs": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.9.tgz", - "integrity": "sha512-KDlPRM6sLo4o1FkiSlXoAa8edLXFsKKIda779fbLrvmeuc3itnjCtaO6RrtoaANsIJANj+Vk1zqbZIMhkCAHVw==", + "license": "MIT", "dependencies": { "@babel/helper-hoist-variables": "^7.22.5", "@babel/helper-module-transforms": "^7.23.3", @@ -1411,8 +1295,7 @@ }, "node_modules/@babel/plugin-transform-modules-umd": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz", - "integrity": "sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg==", + "license": "MIT", "dependencies": { "@babel/helper-module-transforms": "^7.23.3", "@babel/helper-plugin-utils": "^7.22.5" @@ -1426,8 +1309,7 @@ }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz", - "integrity": "sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==", + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -1441,8 +1323,7 @@ }, "node_modules/@babel/plugin-transform-new-target": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz", - "integrity": "sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1455,8 +1336,7 @@ }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz", - "integrity": "sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3" @@ -1470,8 +1350,7 @@ }, "node_modules/@babel/plugin-transform-numeric-separator": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz", - "integrity": "sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-numeric-separator": "^7.10.4" @@ -1485,8 +1364,7 @@ }, "node_modules/@babel/plugin-transform-object-rest-spread": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz", - "integrity": "sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g==", + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.23.3", "@babel/helper-compilation-targets": "^7.22.15", @@ -1503,8 +1381,7 @@ }, "node_modules/@babel/plugin-transform-object-super": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz", - "integrity": "sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-replace-supers": "^7.22.20" @@ -1518,8 +1395,7 @@ }, "node_modules/@babel/plugin-transform-optional-catch-binding": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz", - "integrity": "sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3" @@ -1533,8 +1409,7 @@ }, "node_modules/@babel/plugin-transform-optional-chaining": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz", - "integrity": "sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5", @@ -1549,8 +1424,7 @@ }, "node_modules/@babel/plugin-transform-parameters": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz", - "integrity": "sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1563,8 +1437,7 @@ }, "node_modules/@babel/plugin-transform-private-methods": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz", - "integrity": "sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g==", + "license": "MIT", "dependencies": { "@babel/helper-create-class-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1578,8 +1451,7 @@ }, "node_modules/@babel/plugin-transform-private-property-in-object": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz", - "integrity": "sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.22.15", @@ -1595,8 +1467,7 @@ }, "node_modules/@babel/plugin-transform-property-literals": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz", - "integrity": "sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1609,8 +1480,7 @@ }, "node_modules/@babel/plugin-transform-react-constant-elements": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz", - "integrity": "sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1623,8 +1493,7 @@ }, "node_modules/@babel/plugin-transform-react-display-name": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz", - "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1637,8 +1506,7 @@ }, "node_modules/@babel/plugin-transform-react-jsx": { "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz", - "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-module-imports": "^7.22.15", @@ -1655,8 +1523,7 @@ }, "node_modules/@babel/plugin-transform-react-jsx-development": { "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz", - "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==", + "license": "MIT", "dependencies": { "@babel/plugin-transform-react-jsx": "^7.22.5" }, @@ -1669,8 +1536,7 @@ }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz", - "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-plugin-utils": "^7.22.5" @@ -1684,8 +1550,7 @@ }, "node_modules/@babel/plugin-transform-regenerator": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz", - "integrity": "sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "regenerator-transform": "^0.15.2" @@ -1699,8 +1564,7 @@ }, "node_modules/@babel/plugin-transform-reserved-words": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz", - "integrity": "sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1713,8 +1577,7 @@ }, "node_modules/@babel/plugin-transform-runtime": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz", - "integrity": "sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ==", + "license": "MIT", "dependencies": { "@babel/helper-module-imports": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5", @@ -1732,16 +1595,14 @@ }, "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/plugin-transform-shorthand-properties": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz", - "integrity": "sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1754,8 +1615,7 @@ }, "node_modules/@babel/plugin-transform-spread": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz", - "integrity": "sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.22.5" @@ -1769,8 +1629,7 @@ }, "node_modules/@babel/plugin-transform-sticky-regex": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz", - "integrity": "sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1783,8 +1642,7 @@ }, "node_modules/@babel/plugin-transform-template-literals": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz", - "integrity": "sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1797,8 +1655,7 @@ }, "node_modules/@babel/plugin-transform-typeof-symbol": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz", - "integrity": "sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1811,8 +1668,7 @@ }, "node_modules/@babel/plugin-transform-typescript": { "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz", - "integrity": "sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA==", + "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.22.5", "@babel/helper-create-class-features-plugin": "^7.23.6", @@ -1828,8 +1684,7 @@ }, "node_modules/@babel/plugin-transform-unicode-escapes": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz", - "integrity": "sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5" }, @@ -1842,8 +1697,7 @@ }, "node_modules/@babel/plugin-transform-unicode-property-regex": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz", - "integrity": "sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA==", + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1857,8 +1711,7 @@ }, "node_modules/@babel/plugin-transform-unicode-regex": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz", - "integrity": "sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw==", + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1872,8 +1725,7 @@ }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz", - "integrity": "sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw==", + "license": "MIT", "dependencies": { "@babel/helper-create-regexp-features-plugin": "^7.22.15", "@babel/helper-plugin-utils": "^7.22.5" @@ -1887,8 +1739,7 @@ }, "node_modules/@babel/preset-env": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.23.9.tgz", - "integrity": "sha512-3kBGTNBBk9DQiPoXYS0g0BYlwTQYUTifqgKTjxUwEUkduRT2QOa0FPGBJ+NROQhGyYO5BuTJwGvBnqKDykac6A==", + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.23.5", "@babel/helper-compilation-targets": "^7.23.6", @@ -1980,16 +1831,14 @@ }, "node_modules/@babel/preset-env/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/preset-modules": { "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@babel/types": "^7.4.4", @@ -2001,8 +1850,7 @@ }, "node_modules/@babel/preset-react": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz", - "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", @@ -2020,8 +1868,7 @@ }, "node_modules/@babel/preset-typescript": { "version": "7.23.3", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz", - "integrity": "sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ==", + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.22.5", "@babel/helper-validator-option": "^7.22.15", @@ -2038,13 +1885,11 @@ }, "node_modules/@babel/regjsgen": { "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz", - "integrity": "sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==" + "license": "MIT" }, "node_modules/@babel/runtime": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.9.tgz", - "integrity": "sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw==", + "license": "MIT", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -2054,8 +1899,7 @@ }, "node_modules/@babel/runtime-corejs3": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.23.9.tgz", - "integrity": "sha512-oeOFTrYWdWXCvXGB5orvMTJ6gCZ9I6FBjR+M38iKNXCsPxr4xT0RTdg5uz1H7QP8pp74IzPtwritEr+JscqHXQ==", + "license": "MIT", "dependencies": { "core-js-pure": "^3.30.2", "regenerator-runtime": "^0.14.0" @@ -2066,8 +1910,7 @@ }, "node_modules/@babel/template": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz", - "integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/parser": "^7.23.9", @@ -2079,8 +1922,7 @@ }, "node_modules/@babel/traverse": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz", - "integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.23.5", "@babel/generator": "^7.23.6", @@ -2099,8 +1941,7 @@ }, "node_modules/@babel/types": { "version": "7.23.9", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz", - "integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==", + "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.23.4", "@babel/helper-validator-identifier": "^7.22.20", @@ -2112,8 +1953,7 @@ }, "node_modules/@colors/colors": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "license": "MIT", "optional": true, "engines": { "node": ">=0.1.90" @@ -2121,21 +1961,18 @@ }, "node_modules/@discoveryjs/json-ext": { "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "license": "MIT", "engines": { "node": ">=10.0.0" } }, "node_modules/@docsearch/css": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/css/-/css-3.5.2.tgz", - "integrity": "sha512-SPiDHaWKQZpwR2siD0KQUwlStvIAnEyK6tAE2h2Wuoq8ue9skzhlyVQ1ddzOxX6khULnAALDiR/isSF3bnuciA==" + "license": "MIT" }, "node_modules/@docsearch/react": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/@docsearch/react/-/react-3.5.2.tgz", - "integrity": "sha512-9Ahcrs5z2jq/DcAvYtvlqEBHImbm4YJI8M9y0x6Tqg598P40HTEkX7hsMcIuThI+hTFxRGZ9hll0Wygm2yEjng==", + "license": "MIT", "dependencies": { "@algolia/autocomplete-core": "1.9.3", "@algolia/autocomplete-preset-algolia": "1.9.3", @@ -2165,8 +2002,7 @@ }, "node_modules/@docusaurus/core": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.1.1.tgz", - "integrity": "sha512-2nQfKFcf+MLEM7JXsXwQxPOmQAR6ytKMZVSx7tVi9HEm9WtfwBH1fp6bn8Gj4zLUhjWKCLoysQ9/Wm+EZCQ4yQ==", + "license": "MIT", "dependencies": { "@babel/core": "^7.23.3", "@babel/generator": "^7.23.3", @@ -2251,8 +2087,7 @@ }, "node_modules/@docusaurus/cssnano-preset": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.1.1.tgz", - "integrity": "sha512-LnoIDjJWbirdbVZDMq+4hwmrTl2yHDnBf9MLG9qyExeAE3ac35s4yUhJI8yyTCdixzNfKit4cbXblzzqMu4+8g==", + "license": "MIT", "dependencies": { "cssnano-preset-advanced": "^5.3.10", "postcss": "^8.4.26", @@ -2265,8 +2100,7 @@ }, "node_modules/@docusaurus/logger": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.1.1.tgz", - "integrity": "sha512-BjkNDpQzewcTnST8trx4idSoAla6zZ3w22NqM/UMcFtvYJgmoE4layuTzlfql3VFPNuivvj7BOExa/+21y4X2Q==", + "license": "MIT", "dependencies": { "chalk": "^4.1.2", "tslib": "^2.6.0" @@ -2277,8 +2111,7 @@ }, "node_modules/@docusaurus/mdx-loader": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.1.1.tgz", - "integrity": "sha512-xN2IccH9+sv7TmxwsDJNS97BHdmlqWwho+kIVY4tcCXkp+k4QuzvWBeunIMzeayY4Fu13A6sAjHGv5qm72KyGA==", + "license": "MIT", "dependencies": { "@babel/parser": "^7.22.7", "@babel/traverse": "^7.22.8", @@ -2317,8 +2150,7 @@ }, "node_modules/@docusaurus/module-type-aliases": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.1.1.tgz", - "integrity": "sha512-xBJyx0TMfAfVZ9ZeIOb1awdXgR4YJMocIEzTps91rq+hJDFJgJaylDtmoRhUxkwuYmNK1GJpW95b7DLztSBJ3A==", + "license": "MIT", "dependencies": { "@docusaurus/react-loadable": "5.5.2", "@docusaurus/types": "3.1.1", @@ -2336,8 +2168,7 @@ }, "node_modules/@docusaurus/plugin-content-blog": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.1.1.tgz", - "integrity": "sha512-ew/3VtVoG3emoAKmoZl7oKe1zdFOsI0NbcHS26kIxt2Z8vcXKCUgK9jJJrz0TbOipyETPhqwq4nbitrY3baibg==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/logger": "3.1.1", @@ -2367,8 +2198,7 @@ }, "node_modules/@docusaurus/plugin-content-docs": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.1.1.tgz", - "integrity": "sha512-lhFq4E874zw0UOH7ujzxnCayOyAt0f9YPVYSb9ohxrdCM8B4szxitUw9rIX4V9JLLHVoqIJb6k+lJJ1jrcGJ0A==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/logger": "3.1.1", @@ -2396,8 +2226,7 @@ }, "node_modules/@docusaurus/plugin-content-pages": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.1.1.tgz", - "integrity": "sha512-NQHncNRAJbyLtgTim9GlEnNYsFhuCxaCNkMwikuxLTiGIPH7r/jpb7O3f3jUMYMebZZZrDq5S7om9a6rvB/YCA==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/mdx-loader": "3.1.1", @@ -2418,8 +2247,7 @@ }, "node_modules/@docusaurus/plugin-debug": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.1.1.tgz", - "integrity": "sha512-xWeMkueM9wE/8LVvl4+Qf1WqwXmreMjI5Kgr7GYCDoJ8zu4kD+KaMhrh7py7MNM38IFvU1RfrGKacCEe2DRRfQ==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/types": "3.1.1", @@ -2438,8 +2266,7 @@ }, "node_modules/@docusaurus/plugin-google-analytics": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.1.1.tgz", - "integrity": "sha512-+q2UpWTqVi8GdlLoSlD5bS/YpxW+QMoBwrPrUH/NpvpuOi0Of7MTotsQf9JWd3hymZxl2uu1o3PIrbpxfeDFDQ==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/types": "3.1.1", @@ -2456,8 +2283,7 @@ }, "node_modules/@docusaurus/plugin-google-gtag": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.1.1.tgz", - "integrity": "sha512-0mMPiBBlQ5LFHTtjxuvt/6yzh8v7OxLi3CbeEsxXZpUzcKO/GC7UA1VOWUoBeQzQL508J12HTAlR3IBU9OofSw==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/types": "3.1.1", @@ -2475,8 +2301,7 @@ }, "node_modules/@docusaurus/plugin-google-tag-manager": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.1.1.tgz", - "integrity": "sha512-d07bsrMLdDIryDtY17DgqYUbjkswZQr8cLWl4tzXrt5OR/T/zxC1SYKajzB3fd87zTu5W5klV5GmUwcNSMXQXA==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/types": "3.1.1", @@ -2493,8 +2318,7 @@ }, "node_modules/@docusaurus/plugin-sitemap": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.1.1.tgz", - "integrity": "sha512-iJ4hCaMmDaUqRv131XJdt/C/jJQx8UreDWTRqZKtNydvZVh/o4yXGRRFOplea1D9b/zpwL1Y+ZDwX7xMhIOTmg==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/logger": "3.1.1", @@ -2516,8 +2340,7 @@ }, "node_modules/@docusaurus/preset-classic": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.1.1.tgz", - "integrity": "sha512-jG4ys/hWYf69iaN/xOmF+3kjs4Nnz1Ay3CjFLDtYa8KdxbmUhArA9HmP26ru5N0wbVWhY+6kmpYhTJpez5wTyg==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/plugin-content-blog": "3.1.1", @@ -2543,8 +2366,7 @@ }, "node_modules/@docusaurus/react-loadable": { "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "license": "MIT", "dependencies": { "@types/react": "*", "prop-types": "^15.6.2" @@ -2555,8 +2377,7 @@ }, "node_modules/@docusaurus/theme-classic": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.1.1.tgz", - "integrity": "sha512-GiPE/jbWM8Qv1A14lk6s9fhc0LhPEQ00eIczRO4QL2nAQJZXkjPG6zaVx+1cZxPFWbAsqSjKe2lqkwF3fGkQ7Q==", + "license": "MIT", "dependencies": { "@docusaurus/core": "3.1.1", "@docusaurus/mdx-loader": "3.1.1", @@ -2594,8 +2415,7 @@ }, "node_modules/@docusaurus/theme-common": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.1.1.tgz", - "integrity": "sha512-38urZfeMhN70YaXkwIGXmcUcv2CEYK/2l4b05GkJPrbEbgpsIZM3Xc+Js2ehBGGZmfZq8GjjQ5RNQYG+MYzCYg==", + "license": "MIT", "dependencies": { "@docusaurus/mdx-loader": "3.1.1", "@docusaurus/module-type-aliases": "3.1.1", @@ -2623,8 +2443,7 @@ }, "node_modules/@docusaurus/theme-search-algolia": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.1.1.tgz", - "integrity": "sha512-tBH9VY5EpRctVdaAhT+b1BY8y5dyHVZGFXyCHgTrvcXQy5CV4q7serEX7U3SveNT9zksmchPyct6i1sFDC4Z5g==", + "license": "MIT", "dependencies": { "@docsearch/react": "^3.5.2", "@docusaurus/core": "3.1.1", @@ -2653,8 +2472,7 @@ }, "node_modules/@docusaurus/theme-translations": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.1.1.tgz", - "integrity": "sha512-xvWQFwjxHphpJq5fgk37FXCDdAa2o+r7FX8IpMg+bGZBNXyWBu3MjZ+G4+eUVNpDhVinTc+j6ucL0Ain5KCGrg==", + "license": "MIT", "dependencies": { "fs-extra": "^11.1.1", "tslib": "^2.6.0" @@ -2665,14 +2483,12 @@ }, "node_modules/@docusaurus/tsconfig": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.1.1.tgz", - "integrity": "sha512-FTBuY3KvaHfMVBgvlPmDQ+KS9Q/bYtVftq2ugou3PgBDJoQmw2aUZ4Sg15HKqLGbfIkxoy9t6cqE4Yw1Ta8Q1A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@docusaurus/types": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.1.1.tgz", - "integrity": "sha512-grBqOLnubUecgKFXN9q3uit2HFbCxTWX4Fam3ZFbMN0sWX9wOcDoA7lwdX/8AmeL20Oc4kQvWVgNrsT8bKRvzg==", + "license": "MIT", "dependencies": { "@mdx-js/mdx": "^3.0.0", "@types/history": "^4.7.11", @@ -2691,8 +2507,7 @@ }, "node_modules/@docusaurus/utils": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.1.1.tgz", - "integrity": "sha512-ZJfJa5cJQtRYtqijsPEnAZoduW6sjAQ7ZCWSZavLcV10Fw0Z3gSaPKA/B4micvj2afRZ4gZxT7KfYqe5H8Cetg==", + "license": "MIT", "dependencies": { "@docusaurus/logger": "3.1.1", "@svgr/webpack": "^6.5.1", @@ -2726,8 +2541,7 @@ }, "node_modules/@docusaurus/utils-common": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.1.1.tgz", - "integrity": "sha512-eGne3olsIoNfPug5ixjepZAIxeYFzHHnor55Wb2P57jNbtVaFvij/T+MS8U0dtZRFi50QU+UPmRrXdVUM8uyMg==", + "license": "MIT", "dependencies": { "tslib": "^2.6.0" }, @@ -2745,8 +2559,7 @@ }, "node_modules/@docusaurus/utils-validation": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.1.1.tgz", - "integrity": "sha512-KlY4P9YVDnwL+nExvlIpu79abfEv6ZCHuOX4ZQ+gtip+Wxj0daccdReIWWtqxM/Fb5Cz1nQvUCc7VEtT8IBUAA==", + "license": "MIT", "dependencies": { "@docusaurus/logger": "3.1.1", "@docusaurus/utils": "3.1.1", @@ -2760,21 +2573,18 @@ }, "node_modules/@hapi/hoek": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==" + "license": "BSD-3-Clause" }, "node_modules/@hapi/topo": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", + "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@jest/schemas": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "license": "MIT", "dependencies": { "@sinclair/typebox": "^0.27.8" }, @@ -2784,8 +2594,7 @@ }, "node_modules/@jest/types": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "license": "MIT", "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", @@ -2800,8 +2609,7 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "license": "MIT", "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", @@ -2813,24 +2621,21 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", - "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", + "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.0", "@jridgewell/trace-mapping": "^0.3.9" @@ -2838,13 +2643,11 @@ }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.22", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", - "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" @@ -2852,13 +2655,11 @@ }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", - "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==" + "license": "MIT" }, "node_modules/@mdx-js/mdx": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.0.1.tgz", - "integrity": "sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", @@ -2891,8 +2692,7 @@ }, "node_modules/@mdx-js/react": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-3.0.1.tgz", - "integrity": "sha512-9ZrPIU4MGf6et1m1ov3zKf+q9+deetI51zprKB1D/z3NOb+rUxxtEl3mCjW5wTGh6VhRdwPueh1oRzi6ezkA8A==", + "license": "MIT", "dependencies": { "@types/mdx": "^2.0.0" }, @@ -2907,8 +2707,7 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2919,16 +2718,14 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2939,16 +2736,14 @@ }, "node_modules/@pnpm/config.env-replace": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "license": "MIT", "engines": { "node": ">=12.22.0" } }, "node_modules/@pnpm/network.ca-file": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "license": "MIT", "dependencies": { "graceful-fs": "4.2.10" }, @@ -2958,13 +2753,11 @@ }, "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "license": "ISC" }, "node_modules/@pnpm/npm-conf": { "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz", - "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==", + "license": "MIT", "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", @@ -2976,36 +2769,30 @@ }, "node_modules/@polka/url": { "version": "1.0.0-next.24", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.24.tgz", - "integrity": "sha512-2LuNTFBIO0m7kKIQvvPHN6UE63VjpmL9rnEEaOOaiSPbZK+zUOYIzBAWcED+3XYzhYsd/0mD57VdxAEqqV52CQ==" + "license": "MIT" }, "node_modules/@sideway/address": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", + "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.0.0" } }, "node_modules/@sideway/formula": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==" + "license": "BSD-3-Clause" }, "node_modules/@sideway/pinpoint": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==" + "license": "BSD-3-Clause" }, "node_modules/@sinclair/typebox": { "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==" + "license": "MIT" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3015,8 +2802,7 @@ }, "node_modules/@slorber/remark-comment": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@slorber/remark-comment/-/remark-comment-1.0.0.tgz", - "integrity": "sha512-RCE24n7jsOj1M0UPvIQCHTe7fI0sFL4S2nwKVWwHyVr/wI/H8GosgsJGyhnsZoGFnD/P2hLf1mSbrrgSLN93NA==", + "license": "MIT", "dependencies": { "micromark-factory-space": "^1.0.0", "micromark-util-character": "^1.1.0", @@ -3025,8 +2811,7 @@ }, "node_modules/@slorber/static-site-generator-webpack-plugin": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@slorber/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-4.0.7.tgz", - "integrity": "sha512-Ug7x6z5lwrz0WqdnNFOMYrDQNTPAprvHLSh6+/fmml3qUiz6l5eq+2MzLKWtn/q5K5NpSiFsZTP/fck/3vjSxA==", + "license": "MIT", "dependencies": { "eval": "^0.1.8", "p-map": "^4.0.0", @@ -3038,8 +2823,7 @@ }, "node_modules/@svgr/babel-plugin-add-jsx-attribute": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz", - "integrity": "sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3053,8 +2837,7 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-attribute": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz", - "integrity": "sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -3068,8 +2851,7 @@ }, "node_modules/@svgr/babel-plugin-remove-jsx-empty-expression": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz", - "integrity": "sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -3083,8 +2865,7 @@ }, "node_modules/@svgr/babel-plugin-replace-jsx-attribute-value": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz", - "integrity": "sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3098,8 +2879,7 @@ }, "node_modules/@svgr/babel-plugin-svg-dynamic-title": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz", - "integrity": "sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3113,8 +2893,7 @@ }, "node_modules/@svgr/babel-plugin-svg-em-dimensions": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz", - "integrity": "sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3128,8 +2907,7 @@ }, "node_modules/@svgr/babel-plugin-transform-react-native-svg": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz", - "integrity": "sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -3143,8 +2921,7 @@ }, "node_modules/@svgr/babel-plugin-transform-svg-component": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz", - "integrity": "sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -3158,8 +2935,7 @@ }, "node_modules/@svgr/babel-preset": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.5.1.tgz", - "integrity": "sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==", + "license": "MIT", "dependencies": { "@svgr/babel-plugin-add-jsx-attribute": "^6.5.1", "@svgr/babel-plugin-remove-jsx-attribute": "*", @@ -3183,8 +2959,7 @@ }, "node_modules/@svgr/core": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-6.5.1.tgz", - "integrity": "sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==", + "license": "MIT", "dependencies": { "@babel/core": "^7.19.6", "@svgr/babel-preset": "^6.5.1", @@ -3202,8 +2977,7 @@ }, "node_modules/@svgr/hast-util-to-babel-ast": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz", - "integrity": "sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==", + "license": "MIT", "dependencies": { "@babel/types": "^7.20.0", "entities": "^4.4.0" @@ -3218,8 +2992,7 @@ }, "node_modules/@svgr/plugin-jsx": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz", - "integrity": "sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==", + "license": "MIT", "dependencies": { "@babel/core": "^7.19.6", "@svgr/babel-preset": "^6.5.1", @@ -3239,8 +3012,7 @@ }, "node_modules/@svgr/plugin-svgo": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz", - "integrity": "sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==", + "license": "MIT", "dependencies": { "cosmiconfig": "^7.0.1", "deepmerge": "^4.2.2", @@ -3259,8 +3031,7 @@ }, "node_modules/@svgr/webpack": { "version": "6.5.1", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.5.1.tgz", - "integrity": "sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==", + "license": "MIT", "dependencies": { "@babel/core": "^7.19.6", "@babel/plugin-transform-react-constant-elements": "^7.18.12", @@ -3281,8 +3052,7 @@ }, "node_modules/@szmarczak/http-timer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "license": "MIT", "dependencies": { "defer-to-connect": "^2.0.1" }, @@ -3292,24 +3062,21 @@ }, "node_modules/@trysound/sax": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "license": "ISC", "engines": { "node": ">=10.13.0" } }, "node_modules/@types/acorn": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/@types/body-parser": { "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "license": "MIT", "dependencies": { "@types/connect": "*", "@types/node": "*" @@ -3317,24 +3084,21 @@ }, "node_modules/@types/bonjour": { "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect": { "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/connect-history-api-fallback": { "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "license": "MIT", "dependencies": { "@types/express-serve-static-core": "*", "@types/node": "*" @@ -3342,16 +3106,14 @@ }, "node_modules/@types/debug": { "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", "dependencies": { "@types/ms": "*" } }, "node_modules/@types/eslint": { "version": "8.56.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.2.tgz", - "integrity": "sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw==", + "license": "MIT", "dependencies": { "@types/estree": "*", "@types/json-schema": "*" @@ -3359,8 +3121,7 @@ }, "node_modules/@types/eslint-scope": { "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "license": "MIT", "dependencies": { "@types/eslint": "*", "@types/estree": "*" @@ -3368,21 +3129,18 @@ }, "node_modules/@types/estree": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" + "license": "MIT" }, "node_modules/@types/estree-jsx": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.4.tgz", - "integrity": "sha512-5idy3hvI9lAMqsyilBM+N+boaCf1MgoefbDxN6KEO5aK17TOHwFAYT9sjxzeKAiIWRUBgLxmZ9mPcnzZXtTcRQ==", + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/@types/express": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", @@ -3392,8 +3150,7 @@ }, "node_modules/@types/express-serve-static-core": { "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "license": "MIT", "dependencies": { "@types/node": "*", "@types/qs": "*", @@ -3403,139 +3160,116 @@ }, "node_modules/@types/gtag.js": { "version": "0.0.12", - "resolved": "https://registry.npmjs.org/@types/gtag.js/-/gtag.js-0.0.12.tgz", - "integrity": "sha512-YQV9bUsemkzG81Ea295/nF/5GijnD2Af7QhEofh7xu+kvCN6RdodgNwwGWXB5GMI3NoyvQo0odNctoH/qLMIpg==" + "license": "MIT" }, "node_modules/@types/hast": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", - "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", "dependencies": { "@types/unist": "*" } }, "node_modules/@types/history": { "version": "4.7.11", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.11.tgz", - "integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==" + "license": "MIT" }, "node_modules/@types/html-minifier-terser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==" + "license": "MIT" }, "node_modules/@types/http-cache-semantics": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==" + "license": "MIT" }, "node_modules/@types/http-errors": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==" + "license": "MIT" }, "node_modules/@types/http-proxy": { "version": "1.17.14", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.14.tgz", - "integrity": "sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==" + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/json-schema": { "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + "license": "MIT" }, "node_modules/@types/mdast": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.3.tgz", - "integrity": "sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==", + "license": "MIT", "dependencies": { "@types/unist": "*" } }, "node_modules/@types/mdx": { "version": "2.0.11", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.11.tgz", - "integrity": "sha512-HM5bwOaIQJIQbAYfax35HCKxx7a3KrK3nBtIqJgSOitivTD1y3oW9P3rxY9RkXYPUk7y/AjAohfHKmFpGE79zw==" + "license": "MIT" }, "node_modules/@types/mime": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" + "license": "MIT" }, "node_modules/@types/ms": { "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + "license": "MIT" }, "node_modules/@types/node": { "version": "20.11.19", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", - "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", + "license": "MIT", "dependencies": { "undici-types": "~5.26.4" } }, "node_modules/@types/node-forge": { "version": "1.3.11", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.11.tgz", - "integrity": "sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/parse-json": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" + "license": "MIT" }, "node_modules/@types/prismjs": { "version": "1.26.3", - "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.3.tgz", - "integrity": "sha512-A0D0aTXvjlqJ5ZILMz3rNfDBOx9hHxLZYv2by47Sm/pqW35zzjusrZTryatjN/Rf8Us2gZrJD+KeHbUSTux1Cw==" + "license": "MIT" }, "node_modules/@types/prop-types": { "version": "15.7.11", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", - "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==" + "license": "MIT" }, "node_modules/@types/qs": { "version": "6.9.11", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz", - "integrity": "sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ==" + "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==" + "license": "MIT" }, "node_modules/@types/react": { "version": "18.2.56", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.56.tgz", - "integrity": "sha512-NpwHDMkS/EFZF2dONFQHgkPRwhvgq/OAvIaGQzxGSBmaeR++kTg6njr15Vatz0/2VcCEwJQFi6Jf4Q0qBu0rLA==", + "license": "MIT", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3544,8 +3278,7 @@ }, "node_modules/@types/react-router": { "version": "5.1.20", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.20.tgz", - "integrity": "sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q==", + "license": "MIT", "dependencies": { "@types/history": "^4.7.11", "@types/react": "*" @@ -3553,8 +3286,7 @@ }, "node_modules/@types/react-router-config": { "version": "5.0.11", - "resolved": "https://registry.npmjs.org/@types/react-router-config/-/react-router-config-5.0.11.tgz", - "integrity": "sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==", + "license": "MIT", "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -3563,8 +3295,7 @@ }, "node_modules/@types/react-router-dom": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.3.tgz", - "integrity": "sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw==", + "license": "MIT", "dependencies": { "@types/history": "^4.7.11", "@types/react": "*", @@ -3573,26 +3304,22 @@ }, "node_modules/@types/retry": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==" + "license": "MIT" }, "node_modules/@types/sax": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", - "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/scheduler": { "version": "0.16.8", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", - "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" + "license": "MIT" }, "node_modules/@types/send": { "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "license": "MIT", "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -3600,16 +3327,14 @@ }, "node_modules/@types/serve-index": { "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "license": "MIT", "dependencies": { "@types/express": "*" } }, "node_modules/@types/serve-static": { "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "license": "MIT", "dependencies": { "@types/http-errors": "*", "@types/mime": "*", @@ -3618,47 +3343,40 @@ }, "node_modules/@types/sockjs": { "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/unist": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", - "integrity": "sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==" + "license": "MIT" }, "node_modules/@types/ws": { "version": "8.5.10", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", - "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/yargs": { "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==" + "license": "MIT" }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + "license": "ISC" }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -3666,23 +3384,19 @@ }, "node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==" + "license": "MIT" }, "node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==" + "license": "MIT" }, "node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==" + "license": "MIT" }, "node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3691,13 +3405,11 @@ }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==" + "license": "MIT" }, "node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -3707,29 +3419,25 @@ }, "node_modules/@webassemblyjs/ieee754": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==" + "license": "MIT" }, "node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -3743,8 +3451,7 @@ }, "node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -3755,8 +3462,7 @@ }, "node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -3766,8 +3472,7 @@ }, "node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -3779,8 +3484,7 @@ }, "node_modules/@webassemblyjs/wast-printer": { "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" @@ -3788,18 +3492,15 @@ }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==" + "license": "BSD-3-Clause" }, "node_modules/@xtuc/long": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" + "license": "Apache-2.0" }, "node_modules/accepts": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -3810,16 +3511,14 @@ }, "node_modules/accepts/node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/accepts/node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -3829,8 +3528,7 @@ }, "node_modules/acorn": { "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -3840,40 +3538,35 @@ }, "node_modules/acorn-import-assertions": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "license": "MIT", "peerDependencies": { "acorn": "^8" } }, "node_modules/acorn-jsx": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", + "license": "MIT", "engines": { "node": ">=0.4.0" } }, "node_modules/address": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.2.2.tgz", - "integrity": "sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/aggregate-error": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "license": "MIT", "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" @@ -3884,8 +3577,7 @@ }, "node_modules/ajv": { "version": "8.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", - "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -3899,8 +3591,7 @@ }, "node_modules/ajv-formats": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "license": "MIT", "dependencies": { "ajv": "^8.0.0" }, @@ -3915,8 +3606,7 @@ }, "node_modules/ajv-keywords": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3" }, @@ -3926,8 +3616,7 @@ }, "node_modules/algoliasearch": { "version": "4.22.1", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-4.22.1.tgz", - "integrity": "sha512-jwydKFQJKIx9kIZ8Jm44SdpigFwRGPESaxZBaHSV0XWN2yBJAOT4mT7ppvlrpA4UGzz92pqFnVKr/kaZXrcreg==", + "license": "MIT", "dependencies": { "@algolia/cache-browser-local-storage": "4.22.1", "@algolia/cache-common": "4.22.1", @@ -3947,8 +3636,7 @@ }, "node_modules/algoliasearch-helper": { "version": "3.16.2", - "resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.16.2.tgz", - "integrity": "sha512-Yl/Gu5Cq4Z5s/AJ0jR37OPI1H3+z7PHz657ibyaXgMOaWvPlZ3OACN13N+7HCLPUlB0BN+8BtmrG/CqTilowBA==", + "license": "MIT", "dependencies": { "@algolia/events": "^4.0.1" }, @@ -3958,21 +3646,18 @@ }, "node_modules/ansi-align": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", "dependencies": { "string-width": "^4.1.0" } }, "node_modules/ansi-align/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "license": "MIT" }, "node_modules/ansi-align/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -3984,27 +3669,24 @@ }, "node_modules/ansi-html-community": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", "engines": [ "node >= 0.8.0" ], + "license": "Apache-2.0", "bin": { "ansi-html": "bin/ansi-html" } }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -4017,8 +3699,7 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -4029,47 +3710,39 @@ }, "node_modules/arg": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "license": "Python-2.0" }, "node_modules/array-flatten": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "license": "MIT" }, "node_modules/array-union": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/astring": { "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", + "license": "MIT", "bin": { "astring": "bin/astring" } }, "node_modules/at-least-node": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "license": "ISC", "engines": { "node": ">= 4.0.0" } }, "node_modules/autoprefixer": { "version": "10.4.17", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.17.tgz", - "integrity": "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg==", "funding": [ { "type": "opencollective", @@ -4084,6 +3757,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "browserslist": "^4.22.2", "caniuse-lite": "^1.0.30001578", @@ -4104,8 +3778,7 @@ }, "node_modules/babel-loader": { "version": "9.1.3", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.1.3.tgz", - "integrity": "sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw==", + "license": "MIT", "dependencies": { "find-cache-dir": "^4.0.0", "schema-utils": "^4.0.0" @@ -4120,16 +3793,14 @@ }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", - "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", - "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "license": "MIT", "dependencies": { "object.assign": "^4.1.0" } }, "node_modules/babel-plugin-polyfill-corejs2": { "version": "0.4.8", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz", - "integrity": "sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg==", + "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", "@babel/helper-define-polyfill-provider": "^0.5.0", @@ -4141,16 +3812,14 @@ }, "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/babel-plugin-polyfill-corejs3": { "version": "0.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz", - "integrity": "sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg==", + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0", "core-js-compat": "^3.34.0" @@ -4161,8 +3830,7 @@ }, "node_modules/babel-plugin-polyfill-regenerator": { "version": "0.5.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz", - "integrity": "sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg==", + "license": "MIT", "dependencies": { "@babel/helper-define-polyfill-provider": "^0.5.0" }, @@ -4172,8 +3840,7 @@ }, "node_modules/bail": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4181,34 +3848,29 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + "license": "MIT" }, "node_modules/batch": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" + "license": "MIT" }, "node_modules/big.js": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "license": "MIT", "engines": { "node": "*" } }, "node_modules/binary-extensions": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/body-parser": { "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -4230,29 +3892,25 @@ }, "node_modules/body-parser/node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/body-parser/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/bonjour-service": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.2.1.tgz", - "integrity": "sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" @@ -4260,13 +3918,11 @@ }, "node_modules/boolbase": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + "license": "ISC" }, "node_modules/boxen": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-6.2.1.tgz", - "integrity": "sha512-H4PEsJXfFI/Pt8sjDWbHlQPx4zL/bvSQjcilJmaulGt5mLDorHOHpmdXAJcBcmru7PhYSp/cDMWRko4ZUMFkSw==", + "license": "MIT", "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^6.2.0", @@ -4286,8 +3942,7 @@ }, "node_modules/brace-expansion": { "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4295,8 +3950,7 @@ }, "node_modules/braces": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "license": "MIT", "dependencies": { "fill-range": "^7.0.1" }, @@ -4306,8 +3960,6 @@ }, "node_modules/browserslist": { "version": "4.23.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz", - "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==", "funding": [ { "type": "opencollective", @@ -4322,6 +3974,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", @@ -4337,29 +3990,25 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "license": "MIT" }, "node_modules/bytes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/cacheable-lookup": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "license": "MIT", "engines": { "node": ">=14.16" } }, "node_modules/cacheable-request": { "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "license": "MIT", "dependencies": { "@types/http-cache-semantics": "^4.0.2", "get-stream": "^6.0.1", @@ -4375,8 +4024,7 @@ }, "node_modules/cacheable-request/node_modules/normalize-url": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", - "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -4386,8 +4034,7 @@ }, "node_modules/call-bind": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -4404,16 +4051,14 @@ }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/camel-case": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" @@ -4421,8 +4066,7 @@ }, "node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -4432,8 +4076,7 @@ }, "node_modules/caniuse-api": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "license": "MIT", "dependencies": { "browserslist": "^4.0.0", "caniuse-lite": "^1.0.0", @@ -4443,8 +4086,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001588", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001588.tgz", - "integrity": "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ==", "funding": [ { "type": "opencollective", @@ -4458,12 +4099,12 @@ "type": "github", "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/ccount": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4471,8 +4112,7 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4486,16 +4126,14 @@ }, "node_modules/char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/character-entities": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4503,8 +4141,7 @@ }, "node_modules/character-entities-html4": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4512,8 +4149,7 @@ }, "node_modules/character-entities-legacy": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4521,8 +4157,7 @@ }, "node_modules/character-reference-invalid": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4530,8 +4165,7 @@ }, "node_modules/cheerio": { "version": "1.0.0-rc.12", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz", - "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==", + "license": "MIT", "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", @@ -4550,8 +4184,7 @@ }, "node_modules/cheerio-select": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", - "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", @@ -4566,8 +4199,7 @@ }, "node_modules/chokidar": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -4589,30 +4221,27 @@ }, "node_modules/chrome-trace-event": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "license": "MIT", "engines": { "node": ">=6.0" } }, "node_modules/ci-info": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/clean-css": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", - "integrity": "sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==", + "license": "MIT", "dependencies": { "source-map": "~0.6.0" }, @@ -4622,24 +4251,21 @@ }, "node_modules/clean-css/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/clean-stack": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/cli-boxes": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -4649,8 +4275,7 @@ }, "node_modules/cli-table3": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz", - "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==", + "license": "MIT", "dependencies": { "string-width": "^4.2.0" }, @@ -4663,13 +4288,11 @@ }, "node_modules/cli-table3/node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "license": "MIT" }, "node_modules/cli-table3/node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -4681,8 +4304,7 @@ }, "node_modules/clone-deep": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "license": "MIT", "dependencies": { "is-plain-object": "^2.0.4", "kind-of": "^6.0.2", @@ -4694,8 +4316,7 @@ }, "node_modules/clone-deep/node_modules/is-plain-object": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "license": "MIT", "dependencies": { "isobject": "^3.0.1" }, @@ -4705,16 +4326,14 @@ }, "node_modules/clsx": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.0.tgz", - "integrity": "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/collapse-white-space": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", - "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4722,8 +4341,7 @@ }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -4733,31 +4351,26 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "license": "MIT" }, "node_modules/colord": { "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==" + "license": "MIT" }, "node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + "license": "MIT" }, "node_modules/combine-promises": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/combine-promises/-/combine-promises-1.2.0.tgz", - "integrity": "sha512-VcQB1ziGD0NXrhKxiwyNbCDmRzs/OShMs2GqW2DlU2A/Sd0nQxE1oWDAE5O0ygSx5mgQOn9eIFh7yKPgFRVkPQ==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/comma-separated-tokens": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -4765,21 +4378,18 @@ }, "node_modules/commander": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "license": "MIT", "engines": { "node": ">= 6" } }, "node_modules/common-path-prefix": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==" + "license": "ISC" }, "node_modules/compressible": { "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "license": "MIT", "dependencies": { "mime-db": ">= 1.43.0 < 2" }, @@ -4789,16 +4399,14 @@ }, "node_modules/compressible/node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/compression": { "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", @@ -4814,31 +4422,26 @@ }, "node_modules/compression/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/compression/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/compression/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" + "license": "MIT" }, "node_modules/config-chain": { "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "license": "MIT", "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" @@ -4846,8 +4449,7 @@ }, "node_modules/configstore": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-6.0.0.tgz", - "integrity": "sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==", + "license": "BSD-2-Clause", "dependencies": { "dot-prop": "^6.0.1", "graceful-fs": "^4.2.6", @@ -4864,55 +4466,47 @@ }, "node_modules/connect-history-api-fallback": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "license": "MIT", "engines": { "node": ">=0.8" } }, "node_modules/consola": { "version": "2.15.3", - "resolved": "https://registry.npmjs.org/consola/-/consola-2.15.3.tgz", - "integrity": "sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==" + "license": "MIT" }, "node_modules/content-disposition": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/content-type": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + "license": "MIT" }, "node_modules/cookie": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "license": "MIT" }, "node_modules/copy-text-to-clipboard": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/copy-text-to-clipboard/-/copy-text-to-clipboard-3.2.0.tgz", - "integrity": "sha512-RnJFp1XR/LOBDckxTib5Qjr/PMfkatD0MUCQgdpqS8MdKiNUzBjAQBEN6oUy+jW7LI93BBG3DtMB2KOOKpGs2Q==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -4922,8 +4516,7 @@ }, "node_modules/copy-webpack-plugin": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", + "license": "MIT", "dependencies": { "fast-glob": "^3.2.11", "glob-parent": "^6.0.1", @@ -4945,8 +4538,7 @@ }, "node_modules/copy-webpack-plugin/node_modules/glob-parent": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -4956,8 +4548,7 @@ }, "node_modules/copy-webpack-plugin/node_modules/globby": { "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", + "license": "MIT", "dependencies": { "dir-glob": "^3.0.1", "fast-glob": "^3.3.0", @@ -4974,8 +4565,7 @@ }, "node_modules/copy-webpack-plugin/node_modules/slash": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -4985,9 +4575,8 @@ }, "node_modules/core-js": { "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", - "integrity": "sha512-mt7+TUBbTFg5+GngsAxeKBTl5/VS0guFeJacYge9OmHb+m058UwwIm41SE9T4Den7ClatV57B6TYTuJ0CX1MAw==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -4995,8 +4584,7 @@ }, "node_modules/core-js-compat": { "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.36.0.tgz", - "integrity": "sha512-iV9Pd/PsgjNWBXeq8XRtWVSgz2tKAfhfvBs7qxYty+RlRd+OCksaWmOnc4JKrTc1cToXL1N0s3l/vwlxPtdElw==", + "license": "MIT", "dependencies": { "browserslist": "^4.22.3" }, @@ -5007,9 +4595,8 @@ }, "node_modules/core-js-pure": { "version": "3.36.0", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.36.0.tgz", - "integrity": "sha512-cN28qmhRNgbMZZMc/RFu5w8pK9VJzpb2rJVR/lHuZJKwmXnoWOpXmMkxqBB514igkp1Hu8WGROsiOAzUcKdHOQ==", "hasInstallScript": true, + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -5017,13 +4604,11 @@ }, "node_modules/core-util-is": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + "license": "MIT" }, "node_modules/cosmiconfig": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.2.1", @@ -5037,8 +4622,7 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -5050,8 +4634,7 @@ }, "node_modules/crypto-random-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", - "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==", + "license": "MIT", "dependencies": { "type-fest": "^1.0.1" }, @@ -5064,8 +4647,7 @@ }, "node_modules/crypto-random-string/node_modules/type-fest": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -5075,8 +4657,7 @@ }, "node_modules/css-declaration-sorter": { "version": "6.4.1", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz", - "integrity": "sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==", + "license": "ISC", "engines": { "node": "^10 || ^12 || >=14" }, @@ -5086,8 +4667,7 @@ }, "node_modules/css-loader": { "version": "6.10.0", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.10.0.tgz", - "integrity": "sha512-LTSA/jWbwdMlk+rhmElbDR2vbtQoTBPr7fkJE+mxrHj+7ru0hUmHafDRzWIjIHTwpitWVaqY2/UWGRca3yUgRw==", + "license": "MIT", "dependencies": { "icss-utils": "^5.1.0", "postcss": "^8.4.33", @@ -5120,8 +4700,7 @@ }, "node_modules/css-minimizer-webpack-plugin": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-4.2.2.tgz", - "integrity": "sha512-s3Of/4jKfw1Hj9CxEO1E5oXhQAxlayuHO2y/ML+C6I9sQ7FdzfEV6QgMLN3vI+qFsjJGIAFLKtQK7t8BOXAIyA==", + "license": "MIT", "dependencies": { "cssnano": "^5.1.8", "jest-worker": "^29.1.2", @@ -5163,16 +4742,14 @@ }, "node_modules/css-minimizer-webpack-plugin/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/css-select": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", - "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", @@ -5186,8 +4763,7 @@ }, "node_modules/css-tree": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "license": "MIT", "dependencies": { "mdn-data": "2.0.14", "source-map": "^0.6.1" @@ -5198,16 +4774,14 @@ }, "node_modules/css-tree/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/css-what": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "license": "BSD-2-Clause", "engines": { "node": ">= 6" }, @@ -5217,8 +4791,7 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -5228,8 +4801,7 @@ }, "node_modules/cssnano": { "version": "5.1.15", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.15.tgz", - "integrity": "sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==", + "license": "MIT", "dependencies": { "cssnano-preset-default": "^5.2.14", "lilconfig": "^2.0.3", @@ -5248,8 +4820,7 @@ }, "node_modules/cssnano-preset-advanced": { "version": "5.3.10", - "resolved": "https://registry.npmjs.org/cssnano-preset-advanced/-/cssnano-preset-advanced-5.3.10.tgz", - "integrity": "sha512-fnYJyCS9jgMU+cmHO1rPSPf9axbQyD7iUhLO5Df6O4G+fKIOMps+ZbU0PdGFejFBBZ3Pftf18fn1eG7MAPUSWQ==", + "license": "MIT", "dependencies": { "autoprefixer": "^10.4.12", "cssnano-preset-default": "^5.2.14", @@ -5267,8 +4838,7 @@ }, "node_modules/cssnano-preset-default": { "version": "5.2.14", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz", - "integrity": "sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==", + "license": "MIT", "dependencies": { "css-declaration-sorter": "^6.3.1", "cssnano-utils": "^3.1.0", @@ -5309,8 +4879,7 @@ }, "node_modules/cssnano-utils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -5320,8 +4889,7 @@ }, "node_modules/csso": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "license": "MIT", "dependencies": { "css-tree": "^1.1.2" }, @@ -5331,18 +4899,15 @@ }, "node_modules/csstype": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "license": "MIT" }, "node_modules/debounce": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", - "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + "license": "MIT" }, "node_modules/debug": { "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -5357,8 +4922,7 @@ }, "node_modules/decode-named-character-reference": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "license": "MIT", "dependencies": { "character-entities": "^2.0.0" }, @@ -5369,8 +4933,7 @@ }, "node_modules/decompress-response": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", "dependencies": { "mimic-response": "^3.1.0" }, @@ -5383,8 +4946,7 @@ }, "node_modules/decompress-response/node_modules/mimic-response": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -5394,24 +4956,21 @@ }, "node_modules/deep-extend": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", "engines": { "node": ">=4.0.0" } }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/default-gateway": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "license": "BSD-2-Clause", "dependencies": { "execa": "^5.0.0" }, @@ -5421,16 +4980,14 @@ }, "node_modules/defer-to-connect": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -5445,16 +5002,14 @@ }, "node_modules/define-lazy-prop": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/define-properties": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", @@ -5469,8 +5024,7 @@ }, "node_modules/del": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz", - "integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==", + "license": "MIT", "dependencies": { "globby": "^11.0.1", "graceful-fs": "^4.2.4", @@ -5490,24 +5044,21 @@ }, "node_modules/depd": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/dequal": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/destroy": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" @@ -5515,13 +5066,11 @@ }, "node_modules/detect-node": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + "license": "MIT" }, "node_modules/detect-port": { "version": "1.5.1", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.5.1.tgz", - "integrity": "sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==", + "license": "MIT", "dependencies": { "address": "^1.0.1", "debug": "4" @@ -5533,8 +5082,7 @@ }, "node_modules/detect-port-alt": { "version": "1.1.6", - "resolved": "https://registry.npmjs.org/detect-port-alt/-/detect-port-alt-1.1.6.tgz", - "integrity": "sha512-5tQykt+LqfJFBEYaDITx7S7cR7mJ/zQmLXZ2qt5w04ainYZw6tBf9dBunMjVeVOdYVRUzUOE4HkY5J7+uttb5Q==", + "license": "MIT", "dependencies": { "address": "^1.0.1", "debug": "^2.6.0" @@ -5549,21 +5097,18 @@ }, "node_modules/detect-port-alt/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/detect-port-alt/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/devlop": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", - "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", "dependencies": { "dequal": "^2.0.0" }, @@ -5574,8 +5119,7 @@ }, "node_modules/dir-glob": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -5585,8 +5129,7 @@ }, "node_modules/dns-packet": { "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "license": "MIT", "dependencies": { "@leichtgewicht/ip-codec": "^2.0.1" }, @@ -5596,16 +5139,14 @@ }, "node_modules/dom-converter": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "license": "MIT", "dependencies": { "utila": "~0.4" } }, "node_modules/dom-serializer": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", - "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.2", @@ -5617,19 +5158,17 @@ }, "node_modules/domelementtype": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } - ] + ], + "license": "BSD-2-Clause" }, "node_modules/domhandler": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", - "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.3.0" }, @@ -5642,8 +5181,7 @@ }, "node_modules/domutils": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", - "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", @@ -5655,8 +5193,7 @@ }, "node_modules/dot-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -5664,8 +5201,7 @@ }, "node_modules/dot-prop": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "license": "MIT", "dependencies": { "is-obj": "^2.0.0" }, @@ -5678,54 +5214,45 @@ }, "node_modules/dot-prop/node_modules/is-obj": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/duplexer": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + "license": "MIT" }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + "license": "MIT" }, "node_modules/ee-first": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" + "license": "MIT" }, "node_modules/electron-to-chromium": { "version": "1.4.673", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz", - "integrity": "sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==" + "license": "ISC" }, "node_modules/emoji-regex": { "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "license": "MIT" }, "node_modules/emojilib": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz", - "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==" + "license": "MIT" }, "node_modules/emojis-list": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/emoticon": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/emoticon/-/emoticon-4.0.1.tgz", - "integrity": "sha512-dqx7eA9YaqyvYtUhJwT4rC1HIp82j5ybS1/vQ42ur+jBe17dJMwZE4+gvL1XadSFfxaPFFGt3Xsw+Y8akThDlw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -5733,16 +5260,14 @@ }, "node_modules/encodeurl": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/enhanced-resolve": { "version": "5.15.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", - "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -5753,8 +5278,7 @@ }, "node_modules/entities": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -5764,16 +5288,14 @@ }, "node_modules/error-ex": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, "node_modules/es-define-property": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -5783,29 +5305,25 @@ }, "node_modules/es-errors": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/es-module-lexer": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", - "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==" + "license": "MIT" }, "node_modules/escalade": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/escape-goat": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-4.0.0.tgz", - "integrity": "sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5815,13 +5333,11 @@ }, "node_modules/escape-html": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -5831,8 +5347,7 @@ }, "node_modules/eslint-scope": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^4.1.1" @@ -5843,8 +5358,7 @@ }, "node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -5855,8 +5369,7 @@ }, "node_modules/esrecurse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -5866,24 +5379,21 @@ }, "node_modules/esrecurse/node_modules/estraverse": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estraverse": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } }, "node_modules/estree-util-attach-comments": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", - "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" }, @@ -5894,8 +5404,7 @@ }, "node_modules/estree-util-build-jsx": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", - "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", @@ -5909,8 +5418,7 @@ }, "node_modules/estree-util-is-identifier-name": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", - "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -5918,8 +5426,7 @@ }, "node_modules/estree-util-to-js": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", - "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", @@ -5932,8 +5439,7 @@ }, "node_modules/estree-util-value-to-estree": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-3.0.1.tgz", - "integrity": "sha512-b2tdzTurEIbwRh+mKrEcaWfu1wgb8J1hVsgREg7FFiecWwK/PhO8X0kyc+0bIcKNtD4sqxIdNoRy6/p/TvECEA==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "is-plain-obj": "^4.0.0" @@ -5947,8 +5453,7 @@ }, "node_modules/estree-util-visit": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", - "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" @@ -5960,24 +5465,21 @@ }, "node_modules/estree-walker": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0" } }, "node_modules/esutils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/eta": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-2.2.0.tgz", - "integrity": "sha512-UVQ72Rqjy/ZKQalzV5dCCJP80GrmPrMxh6NlNf+erV6ObL0ZFkhCstWRawS85z3smdr3d2wXPsZEY7rDPfGd2g==", + "license": "MIT", "engines": { "node": ">=6.0.0" }, @@ -5987,16 +5489,13 @@ }, "node_modules/etag": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/eval": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", "dependencies": { "@types/node": "*", "require-like": ">= 0.1.1" @@ -6007,21 +5506,18 @@ }, "node_modules/eventemitter3": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" + "license": "MIT" }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", "engines": { "node": ">=0.8.x" } }, "node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -6042,8 +5538,7 @@ }, "node_modules/express": { "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", @@ -6083,8 +5578,7 @@ }, "node_modules/express/node_modules/content-disposition": { "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -6094,39 +5588,33 @@ }, "node_modules/express/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/express/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/express/node_modules/path-to-regexp": { "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "license": "MIT" }, "node_modules/express/node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/extend": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "license": "MIT" }, "node_modules/extend-shallow": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", "dependencies": { "is-extendable": "^0.1.0" }, @@ -6136,13 +5624,11 @@ }, "node_modules/fast-deep-equal": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -6156,29 +5642,25 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "license": "MIT" }, "node_modules/fast-url-parser": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", + "license": "MIT", "dependencies": { "punycode": "^1.3.2" } }, "node_modules/fastq": { "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fault": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "license": "MIT", "dependencies": { "format": "^0.2.0" }, @@ -6189,8 +5671,7 @@ }, "node_modules/faye-websocket": { "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" }, @@ -6200,8 +5681,7 @@ }, "node_modules/feed": { "version": "4.2.2", - "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", - "integrity": "sha512-u5/sxGfiMfZNtJ3OvQpXcvotFpYkL0n9u9mM2vkui2nGo8b4wvDkJ8gAkYqbA8QpGyFCv3RK0Z+Iv+9veCS9bQ==", + "license": "MIT", "dependencies": { "xml-js": "^1.6.11" }, @@ -6211,8 +5691,7 @@ }, "node_modules/file-loader": { "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "schema-utils": "^3.0.0" @@ -6230,8 +5709,7 @@ }, "node_modules/file-loader/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6245,21 +5723,18 @@ }, "node_modules/file-loader/node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/file-loader/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "license": "MIT" }, "node_modules/file-loader/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -6275,16 +5750,14 @@ }, "node_modules/filesize": { "version": "8.0.7", - "resolved": "https://registry.npmjs.org/filesize/-/filesize-8.0.7.tgz", - "integrity": "sha512-pjmC+bkIF8XI7fWaH8KxHcZL3DPybs1roSKP4rKDvy20tAWwIObE4+JIseG2byfGKhud5ZnM4YSGKBz7Sh0ndQ==", + "license": "BSD-3-Clause", "engines": { "node": ">= 0.4.0" } }, "node_modules/fill-range": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -6294,8 +5767,7 @@ }, "node_modules/finalhandler": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -6311,21 +5783,18 @@ }, "node_modules/finalhandler/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/find-cache-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", - "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "license": "MIT", "dependencies": { "common-path-prefix": "^3.0.0", "pkg-dir": "^7.0.0" @@ -6339,8 +5808,7 @@ }, "node_modules/find-up": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", - "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "license": "MIT", "dependencies": { "locate-path": "^7.1.0", "path-exists": "^5.0.0" @@ -6354,22 +5822,20 @@ }, "node_modules/flat": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "license": "BSD-3-Clause", "bin": { "flat": "cli.js" } }, "node_modules/follow-redirects": { "version": "1.15.5", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz", - "integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -6381,8 +5847,7 @@ }, "node_modules/fork-ts-checker-webpack-plugin": { "version": "6.5.3", - "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz", - "integrity": "sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.8.3", "@types/json-schema": "^7.0.5", @@ -6419,8 +5884,7 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -6434,16 +5898,14 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/cosmiconfig": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "license": "MIT", "dependencies": { "@types/parse-json": "^4.0.0", "import-fresh": "^3.1.0", @@ -6457,8 +5919,7 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "license": "MIT", "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", @@ -6471,13 +5932,11 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "license": "MIT" }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/schema-utils": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.4", "ajv": "^6.12.2", @@ -6493,40 +5952,34 @@ }, "node_modules/fork-ts-checker-webpack-plugin/node_modules/tapable": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/form-data-encoder": { "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "license": "MIT", "engines": { "node": ">= 14.17" } }, "node_modules/format": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", "engines": { "node": ">=0.4.x" } }, "node_modules/forwarded": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fraction.js": { "version": "4.3.7", - "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", - "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "license": "MIT", "engines": { "node": "*" }, @@ -6537,16 +5990,14 @@ }, "node_modules/fresh": { "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/fs-extra": { "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -6558,47 +6009,29 @@ }, "node_modules/fs-monkey": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", - "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==" + "license": "Unlicense" }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } + "license": "ISC" }, "node_modules/function-bind": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/get-intrinsic": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -6615,13 +6048,11 @@ }, "node_modules/get-own-enumerable-property-symbols": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==" + "license": "ISC" }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -6631,13 +6062,11 @@ }, "node_modules/github-slugger": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" + "license": "ISC" }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6655,8 +6084,7 @@ }, "node_modules/glob-parent": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -6666,13 +6094,11 @@ }, "node_modules/glob-to-regexp": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==" + "license": "BSD-2-Clause" }, "node_modules/global-dirs": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", + "license": "MIT", "dependencies": { "ini": "2.0.0" }, @@ -6685,16 +6111,14 @@ }, "node_modules/global-dirs/node_modules/ini": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "license": "ISC", "engines": { "node": ">=10" } }, "node_modules/global-modules": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "license": "MIT", "dependencies": { "global-prefix": "^3.0.0" }, @@ -6704,8 +6128,7 @@ }, "node_modules/global-prefix": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "license": "MIT", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -6717,8 +6140,7 @@ }, "node_modules/global-prefix/node_modules/which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -6728,16 +6150,14 @@ }, "node_modules/globals": { "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/globby": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -6755,8 +6175,7 @@ }, "node_modules/gopd": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -6766,8 +6185,7 @@ }, "node_modules/got": { "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "license": "MIT", "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", @@ -6790,8 +6208,7 @@ }, "node_modules/got/node_modules/@sindresorhus/is": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -6801,13 +6218,11 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + "license": "ISC" }, "node_modules/gray-matter": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", @@ -6820,16 +6235,14 @@ }, "node_modules/gray-matter/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } }, "node_modules/gray-matter/node_modules/js-yaml": { "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -6840,8 +6253,7 @@ }, "node_modules/gzip-size": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "license": "MIT", "dependencies": { "duplexer": "^0.1.2" }, @@ -6854,21 +6266,18 @@ }, "node_modules/handle-thing": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" + "license": "MIT" }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -6878,8 +6287,7 @@ }, "node_modules/has-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6889,8 +6297,7 @@ }, "node_modules/has-symbols": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6900,8 +6307,7 @@ }, "node_modules/has-yarn": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-3.0.0.tgz", - "integrity": "sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==", + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -6911,8 +6317,7 @@ }, "node_modules/hasown": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz", - "integrity": "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==", + "license": "MIT", "dependencies": { "function-bind": "^1.1.2" }, @@ -6922,8 +6327,7 @@ }, "node_modules/hast-util-from-parse5": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.1.tgz", - "integrity": "sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", @@ -6941,8 +6345,7 @@ }, "node_modules/hast-util-parse-selector": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", - "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -6953,8 +6356,7 @@ }, "node_modules/hast-util-raw": { "version": "9.0.2", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.0.2.tgz", - "integrity": "sha512-PldBy71wO9Uq1kyaMch9AHIghtQvIwxBUkv823pKmkTM3oV1JxtsTNYdevMxvUHqcnOAuO65JKU2+0NOxc2ksA==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", @@ -6977,8 +6379,7 @@ }, "node_modules/hast-util-to-estree": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.0.tgz", - "integrity": "sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", @@ -7004,8 +6405,7 @@ }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.0.tgz", - "integrity": "sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", @@ -7030,21 +6430,18 @@ }, "node_modules/hast-util-to-jsx-runtime/node_modules/inline-style-parser": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.2.tgz", - "integrity": "sha512-EcKzdTHVe8wFVOGEYXiW9WmJXPjqi1T+234YpJr98RiFYKHV3cdy1+3mkTE+KHTHxFFLH51SfaGOoUdW+v7ViQ==" + "license": "MIT" }, "node_modules/hast-util-to-jsx-runtime/node_modules/style-to-object": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.5.tgz", - "integrity": "sha512-rDRwHtoDD3UMMrmZ6BzOW0naTjMsVZLIjsGleSKS/0Oz+cgCfAPRspaqJuE8rDzpKha/nEvnM0IF4seEAZUTKQ==", + "license": "MIT", "dependencies": { "inline-style-parser": "0.2.2" } }, "node_modules/hast-util-to-parse5": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", - "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", @@ -7061,8 +6458,7 @@ }, "node_modules/hast-util-whitespace": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", - "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0" }, @@ -7073,8 +6469,7 @@ }, "node_modules/hastscript": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-8.0.0.tgz", - "integrity": "sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", @@ -7089,16 +6484,14 @@ }, "node_modules/he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "license": "MIT", "bin": { "he": "bin/he" } }, "node_modules/history": { "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2", "loose-envify": "^1.2.0", @@ -7110,16 +6503,14 @@ }, "node_modules/hoist-non-react-statics": { "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "license": "BSD-3-Clause", "dependencies": { "react-is": "^16.7.0" } }, "node_modules/hpack.js": { "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "license": "MIT", "dependencies": { "inherits": "^2.0.1", "obuf": "^1.0.0", @@ -7129,13 +6520,11 @@ }, "node_modules/hpack.js/node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" + "license": "MIT" }, "node_modules/hpack.js/node_modules/readable-stream": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7148,21 +6537,17 @@ }, "node_modules/hpack.js/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "license": "MIT" }, "node_modules/hpack.js/node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.1.0" } }, "node_modules/html-entities": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.4.0.tgz", - "integrity": "sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ==", "funding": [ { "type": "github", @@ -7172,17 +6557,16 @@ "type": "patreon", "url": "https://patreon.com/mdevils" } - ] + ], + "license": "MIT" }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + "license": "MIT" }, "node_modules/html-minifier-terser": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz", - "integrity": "sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==", + "license": "MIT", "dependencies": { "camel-case": "^4.1.2", "clean-css": "~5.3.2", @@ -7201,16 +6585,14 @@ }, "node_modules/html-minifier-terser/node_modules/commander": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "license": "MIT", "engines": { "node": ">=14" } }, "node_modules/html-tags": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", - "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -7220,8 +6602,7 @@ }, "node_modules/html-void-elements": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", - "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7229,8 +6610,7 @@ }, "node_modules/html-webpack-plugin": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz", - "integrity": "sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw==", + "license": "MIT", "dependencies": { "@types/html-minifier-terser": "^6.0.0", "html-minifier-terser": "^6.0.2", @@ -7260,16 +6640,14 @@ }, "node_modules/html-webpack-plugin/node_modules/commander": { "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", "engines": { "node": ">= 12" } }, "node_modules/html-webpack-plugin/node_modules/html-minifier-terser": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "license": "MIT", "dependencies": { "camel-case": "^4.1.2", "clean-css": "^5.2.2", @@ -7288,8 +6666,6 @@ }, "node_modules/htmlparser2": { "version": "8.0.2", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", - "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -7297,6 +6673,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", @@ -7306,18 +6683,15 @@ }, "node_modules/http-cache-semantics": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" + "license": "BSD-2-Clause" }, "node_modules/http-deceiver": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==" + "license": "MIT" }, "node_modules/http-errors": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -7331,13 +6705,11 @@ }, "node_modules/http-parser-js": { "version": "0.5.8", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz", - "integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==" + "license": "MIT" }, "node_modules/http-proxy": { "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "license": "MIT", "dependencies": { "eventemitter3": "^4.0.0", "follow-redirects": "^1.0.0", @@ -7349,8 +6721,7 @@ }, "node_modules/http-proxy-middleware": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "license": "MIT", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", @@ -7372,8 +6743,7 @@ }, "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -7383,8 +6753,7 @@ }, "node_modules/http2-wrapper": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", + "license": "MIT", "dependencies": { "quick-lru": "^5.1.1", "resolve-alpn": "^1.2.0" @@ -7395,16 +6764,14 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/iconv-lite": { "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -7414,8 +6781,7 @@ }, "node_modules/icss-utils": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -7425,16 +6791,14 @@ }, "node_modules/ignore": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/image-size": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.1.1.tgz", - "integrity": "sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==", + "license": "MIT", "dependencies": { "queue": "6.0.2" }, @@ -7447,8 +6811,7 @@ }, "node_modules/immer": { "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "license": "MIT", "funding": { "type": "opencollective", "url": "https://opencollective.com/immer" @@ -7456,8 +6819,7 @@ }, "node_modules/import-fresh": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -7471,40 +6833,35 @@ }, "node_modules/import-lazy": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", "engines": { "node": ">=0.8.19" } }, "node_modules/indent-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/infima": { "version": "0.2.0-alpha.43", - "resolved": "https://registry.npmjs.org/infima/-/infima-0.2.0-alpha.43.tgz", - "integrity": "sha512-2uw57LvUqW0rK/SWYnd/2rRfxNA5DDNOh33jxF7fy46VWoNhGxiUQyVZHbBMjQ33mQem0cjdDVwgWVAmlRfgyQ==", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -7512,47 +6869,40 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + "license": "ISC" }, "node_modules/inline-style-parser": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" + "license": "MIT" }, "node_modules/interpret": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/invariant": { "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "license": "MIT", "dependencies": { "loose-envify": "^1.0.0" } }, "node_modules/ipaddr.js": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.1.0.tgz", - "integrity": "sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ==", + "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/is-alphabetical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7560,8 +6910,7 @@ }, "node_modules/is-alphanumerical": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" @@ -7573,13 +6922,11 @@ }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==" + "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" }, @@ -7589,8 +6936,7 @@ }, "node_modules/is-ci": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "license": "MIT", "dependencies": { "ci-info": "^3.2.0" }, @@ -7600,8 +6946,7 @@ }, "node_modules/is-core-module": { "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "license": "MIT", "dependencies": { "hasown": "^2.0.0" }, @@ -7611,8 +6956,7 @@ }, "node_modules/is-decimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7620,8 +6964,7 @@ }, "node_modules/is-docker": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "license": "MIT", "bin": { "is-docker": "cli.js" }, @@ -7634,32 +6977,28 @@ }, "node_modules/is-extendable": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -7669,8 +7008,7 @@ }, "node_modules/is-hexadecimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7678,8 +7016,7 @@ }, "node_modules/is-installed-globally": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz", - "integrity": "sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==", + "license": "MIT", "dependencies": { "global-dirs": "^3.0.0", "is-path-inside": "^3.0.2" @@ -7693,8 +7030,7 @@ }, "node_modules/is-npm": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-6.0.0.tgz", - "integrity": "sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==", + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -7704,40 +7040,35 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", "engines": { "node": ">=0.12.0" } }, "node_modules/is-obj": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-path-cwd": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", - "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/is-path-inside": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -7747,40 +7078,35 @@ }, "node_modules/is-plain-object": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-reference": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz", - "integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==", + "license": "MIT", "dependencies": { "@types/estree": "*" } }, "node_modules/is-regexp": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/is-root": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-2.1.0.tgz", - "integrity": "sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -7790,13 +7116,11 @@ }, "node_modules/is-typedarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" + "license": "MIT" }, "node_modules/is-wsl": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "license": "MIT", "dependencies": { "is-docker": "^2.0.0" }, @@ -7806,34 +7130,29 @@ }, "node_modules/is-yarn-global": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.4.1.tgz", - "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", + "license": "MIT", "engines": { "node": ">=12" } }, "node_modules/isarray": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "license": "ISC" }, "node_modules/isobject": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/jest-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "license": "MIT", "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", @@ -7848,8 +7167,7 @@ }, "node_modules/jest-worker": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "license": "MIT", "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", @@ -7862,8 +7180,7 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -7876,16 +7193,14 @@ }, "node_modules/jiti": { "version": "1.21.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz", - "integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==", + "license": "MIT", "bin": { "jiti": "bin/jiti.js" } }, "node_modules/joi": { "version": "17.12.1", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.12.1.tgz", - "integrity": "sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ==", + "license": "BSD-3-Clause", "dependencies": { "@hapi/hoek": "^9.3.0", "@hapi/topo": "^5.1.0", @@ -7896,13 +7211,11 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -7912,8 +7225,7 @@ }, "node_modules/jsesc": { "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -7923,23 +7235,19 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -7949,8 +7257,7 @@ }, "node_modules/jsonfile": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", "dependencies": { "universalify": "^2.0.0" }, @@ -7960,32 +7267,28 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, "node_modules/kind-of": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/kleur": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/latest-version": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", + "license": "MIT", "dependencies": { "package-json": "^8.1.0" }, @@ -7998,8 +7301,7 @@ }, "node_modules/launch-editor": { "version": "2.6.1", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.6.1.tgz", - "integrity": "sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw==", + "license": "MIT", "dependencies": { "picocolors": "^1.0.0", "shell-quote": "^1.8.1" @@ -8007,37 +7309,32 @@ }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/lilconfig": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz", - "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" + "license": "MIT" }, "node_modules/loader-runner": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "license": "MIT", "engines": { "node": ">=6.11.5" } }, "node_modules/loader-utils": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "license": "MIT", "dependencies": { "big.js": "^5.2.2", "emojis-list": "^3.0.0", @@ -8049,8 +7346,7 @@ }, "node_modules/locate-path": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", - "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "license": "MIT", "dependencies": { "p-locate": "^6.0.0" }, @@ -8063,28 +7359,23 @@ }, "node_modules/lodash": { "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + "license": "MIT" }, "node_modules/lodash.debounce": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" + "license": "MIT" }, "node_modules/lodash.uniq": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" + "license": "MIT" }, "node_modules/longest-streak": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8092,8 +7383,7 @@ }, "node_modules/loose-envify": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -8103,16 +7393,14 @@ }, "node_modules/lower-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "license": "MIT", "dependencies": { "tslib": "^2.0.3" } }, "node_modules/lowercase-keys": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -8122,16 +7410,14 @@ }, "node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } }, "node_modules/markdown-extensions": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", - "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", "engines": { "node": ">=16" }, @@ -8141,8 +7427,7 @@ }, "node_modules/markdown-table": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8150,8 +7435,7 @@ }, "node_modules/mdast-util-directive": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.0.0.tgz", - "integrity": "sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -8169,8 +7453,7 @@ }, "node_modules/mdast-util-find-and-replace": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.1.tgz", - "integrity": "sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", @@ -8184,8 +7467,7 @@ }, "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -8195,8 +7477,7 @@ }, "node_modules/mdast-util-from-markdown": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.0.tgz", - "integrity": "sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -8218,8 +7499,6 @@ }, "node_modules/mdast-util-from-markdown/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8229,12 +7508,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/mdast-util-frontmatter": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", - "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -8250,8 +7529,7 @@ }, "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -8261,8 +7539,7 @@ }, "node_modules/mdast-util-gfm": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.0.0.tgz", - "integrity": "sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==", + "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", @@ -8279,8 +7556,7 @@ }, "node_modules/mdast-util-gfm-autolink-literal": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", @@ -8295,8 +7571,6 @@ }, "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8307,6 +7581,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8314,8 +7589,6 @@ }, "node_modules/mdast-util-gfm-autolink-literal/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8325,12 +7598,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/mdast-util-gfm-footnote": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", @@ -8345,8 +7618,7 @@ }, "node_modules/mdast-util-gfm-strikethrough": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", @@ -8359,8 +7631,7 @@ }, "node_modules/mdast-util-gfm-table": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", - "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -8375,8 +7646,7 @@ }, "node_modules/mdast-util-gfm-task-list-item": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", - "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", @@ -8390,8 +7660,7 @@ }, "node_modules/mdast-util-mdx": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", - "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx-expression": "^2.0.0", @@ -8406,8 +7675,7 @@ }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.0.tgz", - "integrity": "sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -8423,8 +7691,7 @@ }, "node_modules/mdast-util-mdx-jsx": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.1.0.tgz", - "integrity": "sha512-A8AJHlR7/wPQ3+Jre1+1rq040fX9A4Q1jG8JxmSNp/PLPHg80A6475wxTp3KzHpApFH6yWxFotHrJQA3dXP6/w==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -8447,8 +7714,7 @@ }, "node_modules/mdast-util-mdxjs-esm": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", - "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", @@ -8464,8 +7730,7 @@ }, "node_modules/mdast-util-phrasing": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", - "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" @@ -8477,8 +7742,7 @@ }, "node_modules/mdast-util-to-hast": { "version": "13.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.1.0.tgz", - "integrity": "sha512-/e2l/6+OdGp/FB+ctrJ9Avz71AN/GRH3oi/3KAx/kMnoUsD6q0woXlDT8lLEeViVKE7oZxE7RXzvO3T8kF2/sA==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -8497,8 +7761,7 @@ }, "node_modules/mdast-util-to-markdown": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.0.tgz", - "integrity": "sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", @@ -8516,8 +7779,7 @@ }, "node_modules/mdast-util-to-string": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", - "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0" }, @@ -8528,21 +7790,18 @@ }, "node_modules/mdn-data": { "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + "license": "CC0-1.0" }, "node_modules/media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/memfs": { "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "license": "Unlicense", "dependencies": { "fs-monkey": "^1.0.4" }, @@ -8552,34 +7811,28 @@ }, "node_modules/merge-descriptors": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" + "license": "MIT" }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/methods": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/micromark": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.0.tgz", - "integrity": "sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8590,6 +7843,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", @@ -8612,8 +7866,6 @@ }, "node_modules/micromark-core-commonmark": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.0.tgz", - "integrity": "sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==", "funding": [ { "type": "GitHub Sponsors", @@ -8624,6 +7876,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", @@ -8645,8 +7898,6 @@ }, "node_modules/micromark-core-commonmark/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -8657,6 +7908,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8664,8 +7916,6 @@ }, "node_modules/micromark-core-commonmark/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8676,6 +7926,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8683,8 +7934,6 @@ }, "node_modules/micromark-core-commonmark/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8694,12 +7943,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-directive": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.0.tgz", - "integrity": "sha512-61OI07qpQrERc+0wEysLHMvoiO3s2R56x5u7glHq2Yqq6EHbH4dW25G9GfDdGCDYqA21KE6DWgNSzxSwHc2hSg==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -8716,8 +7965,6 @@ }, "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -8728,6 +7975,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8735,8 +7983,6 @@ }, "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8747,6 +7993,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8754,8 +8001,6 @@ }, "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8765,12 +8010,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-frontmatter": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", - "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "license": "MIT", "dependencies": { "fault": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -8784,8 +8029,6 @@ }, "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8796,6 +8039,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8803,8 +8047,6 @@ }, "node_modules/micromark-extension-frontmatter/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8814,12 +8056,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-gfm": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", - "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", @@ -8837,8 +8079,7 @@ }, "node_modules/micromark-extension-gfm-autolink-literal": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.0.0.tgz", - "integrity": "sha512-rTHfnpt/Q7dEAK1Y5ii0W8bhfJlVJFnJMHIPisfPK3gpVNuOP0VnRl96+YJ3RYWV/P4gFeQoGKNlT3RhuvpqAg==", + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", @@ -8852,8 +8093,6 @@ }, "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8864,6 +8103,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8871,8 +8111,6 @@ }, "node_modules/micromark-extension-gfm-autolink-literal/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8882,12 +8120,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-gfm-footnote": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.0.0.tgz", - "integrity": "sha512-6Rzu0CYRKDv3BfLAUnZsSlzx3ak6HAoI85KTiijuKIz5UxZxbUI+pD6oHgw+6UtQuiRwnGRhzMmPRv4smcz0fg==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", @@ -8905,8 +8143,6 @@ }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -8917,6 +8153,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8924,8 +8161,6 @@ }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -8936,6 +8171,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -8943,8 +8179,6 @@ }, "node_modules/micromark-extension-gfm-footnote/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8954,12 +8188,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-gfm-strikethrough": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.0.0.tgz", - "integrity": "sha512-c3BR1ClMp5fxxmwP6AoOY2fXO9U8uFMKs4ADD66ahLTNcwzSCyRVU4k7LPV5Nxo/VJiR4TdzxRQY2v3qIUceCw==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", @@ -8975,8 +8209,6 @@ }, "node_modules/micromark-extension-gfm-strikethrough/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -8986,12 +8218,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-gfm-table": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.0.0.tgz", - "integrity": "sha512-PoHlhypg1ItIucOaHmKE8fbin3vTLpDOUg8KAr8gRCF1MOZI9Nquq2i/44wFvviM4WuxJzc3demT8Y3dkfvYrw==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -9006,8 +8238,6 @@ }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -9018,6 +8248,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9025,8 +8256,6 @@ }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9037,6 +8266,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9044,8 +8274,6 @@ }, "node_modules/micromark-extension-gfm-table/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9055,12 +8283,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-gfm-tagfilter": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", - "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" }, @@ -9071,8 +8299,7 @@ }, "node_modules/micromark-extension-gfm-task-list-item": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.0.1.tgz", - "integrity": "sha512-cY5PzGcnULaN5O7T+cOzfMoHjBW7j+T9D2sucA5d/KbsBTPcYdebm9zUd9zzdgJGCwahV+/W78Z3nbulBYVbTw==", + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", @@ -9087,8 +8314,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -9099,6 +8324,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9106,8 +8332,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9118,6 +8342,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9125,8 +8350,6 @@ }, "node_modules/micromark-extension-gfm-task-list-item/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9136,12 +8359,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-mdx-expression": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.0.tgz", - "integrity": "sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9152,6 +8374,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", @@ -9165,8 +8388,6 @@ }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -9177,6 +8398,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9184,8 +8406,6 @@ }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9196,6 +8416,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9203,8 +8424,6 @@ }, "node_modules/micromark-extension-mdx-expression/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9214,12 +8433,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-mdx-jsx": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.0.tgz", - "integrity": "sha512-uvhhss8OGuzR4/N17L1JwvmJIpPhAd8oByMawEKx6NVdBCbesjH4t+vjEp3ZXft9DwvlKSD07fCeI44/N0Vf2w==", + "license": "MIT", "dependencies": { "@types/acorn": "^4.0.0", "@types/estree": "^1.0.0", @@ -9239,8 +8458,6 @@ }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -9251,6 +8468,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9258,8 +8476,6 @@ }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9270,6 +8486,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9277,8 +8494,6 @@ }, "node_modules/micromark-extension-mdx-jsx/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9288,12 +8503,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-extension-mdx-md": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", - "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" }, @@ -9304,8 +8519,7 @@ }, "node_modules/micromark-extension-mdxjs": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", - "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", "dependencies": { "acorn": "^8.0.0", "acorn-jsx": "^5.0.0", @@ -9323,8 +8537,7 @@ }, "node_modules/micromark-extension-mdxjs-esm": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", - "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", @@ -9343,8 +8556,6 @@ }, "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9355,6 +8566,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9362,8 +8574,6 @@ }, "node_modules/micromark-extension-mdxjs-esm/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9373,12 +8583,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-factory-destination": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.0.tgz", - "integrity": "sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==", "funding": [ { "type": "GitHub Sponsors", @@ -9389,6 +8598,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -9397,8 +8607,6 @@ }, "node_modules/micromark-factory-destination/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9409,6 +8617,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9416,8 +8625,6 @@ }, "node_modules/micromark-factory-destination/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9427,12 +8634,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-factory-label": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.0.tgz", - "integrity": "sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==", "funding": [ { "type": "GitHub Sponsors", @@ -9443,6 +8649,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", @@ -9452,8 +8659,6 @@ }, "node_modules/micromark-factory-label/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9464,6 +8669,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9471,8 +8677,6 @@ }, "node_modules/micromark-factory-label/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9482,12 +8686,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-factory-mdx-expression": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.1.tgz", - "integrity": "sha512-F0ccWIUHRLRrYp5TC9ZYXmZo+p2AM13ggbsW4T0b5CRKP8KHVRB8t4pwtBgTxtjRmwrK0Irwm7vs2JOZabHZfg==", "funding": [ { "type": "GitHub Sponsors", @@ -9498,6 +8701,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", @@ -9511,8 +8715,6 @@ }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9523,6 +8725,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9530,8 +8733,6 @@ }, "node_modules/micromark-factory-mdx-expression/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9541,12 +8742,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-factory-space": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9557,6 +8757,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^1.0.0", "micromark-util-types": "^1.0.0" @@ -9564,8 +8765,6 @@ }, "node_modules/micromark-factory-space/node_modules/micromark-util-types": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "funding": [ { "type": "GitHub Sponsors", @@ -9575,12 +8774,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-factory-title": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.0.tgz", - "integrity": "sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==", "funding": [ { "type": "GitHub Sponsors", @@ -9591,6 +8789,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -9600,8 +8799,6 @@ }, "node_modules/micromark-factory-title/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -9612,6 +8809,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9619,8 +8817,6 @@ }, "node_modules/micromark-factory-title/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9631,6 +8827,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9638,8 +8835,6 @@ }, "node_modules/micromark-factory-title/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9649,12 +8844,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-factory-whitespace": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.0.tgz", - "integrity": "sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==", "funding": [ { "type": "GitHub Sponsors", @@ -9665,6 +8859,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", @@ -9674,8 +8869,6 @@ }, "node_modules/micromark-factory-whitespace/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -9686,6 +8879,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9693,8 +8887,6 @@ }, "node_modules/micromark-factory-whitespace/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9705,6 +8897,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9712,8 +8905,6 @@ }, "node_modules/micromark-factory-whitespace/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9723,12 +8914,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-character": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", "funding": [ { "type": "GitHub Sponsors", @@ -9739,6 +8929,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^1.0.0", "micromark-util-types": "^1.0.0" @@ -9746,8 +8937,6 @@ }, "node_modules/micromark-util-character/node_modules/micromark-util-types": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", "funding": [ { "type": "GitHub Sponsors", @@ -9757,12 +8946,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-chunked": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.0.tgz", - "integrity": "sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==", "funding": [ { "type": "GitHub Sponsors", @@ -9773,14 +8961,13 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "node_modules/micromark-util-chunked/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9790,12 +8977,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-classify-character": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.0.tgz", - "integrity": "sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==", "funding": [ { "type": "GitHub Sponsors", @@ -9806,6 +8992,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", @@ -9814,8 +9001,6 @@ }, "node_modules/micromark-util-classify-character/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9826,6 +9011,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9833,8 +9019,6 @@ }, "node_modules/micromark-util-classify-character/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9844,12 +9028,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-combine-extensions": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.0.tgz", - "integrity": "sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9860,6 +9043,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9867,8 +9051,6 @@ }, "node_modules/micromark-util-decode-numeric-character-reference": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.1.tgz", - "integrity": "sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9879,14 +9061,13 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "node_modules/micromark-util-decode-numeric-character-reference/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9896,12 +9077,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-decode-string": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.0.tgz", - "integrity": "sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==", "funding": [ { "type": "GitHub Sponsors", @@ -9912,6 +9092,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", @@ -9921,8 +9102,6 @@ }, "node_modules/micromark-util-decode-string/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -9933,6 +9112,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -9940,8 +9120,6 @@ }, "node_modules/micromark-util-decode-string/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -9951,12 +9129,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-encode": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.0.tgz", - "integrity": "sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==", "funding": [ { "type": "GitHub Sponsors", @@ -9966,12 +9143,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-events-to-acorn": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.2.tgz", - "integrity": "sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==", "funding": [ { "type": "GitHub Sponsors", @@ -9982,6 +9158,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "@types/acorn": "^4.0.0", "@types/estree": "^1.0.0", @@ -9995,8 +9172,6 @@ }, "node_modules/micromark-util-events-to-acorn/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -10006,12 +9181,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-html-tag-name": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.0.tgz", - "integrity": "sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==", "funding": [ { "type": "GitHub Sponsors", @@ -10021,12 +9195,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-normalize-identifier": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.0.tgz", - "integrity": "sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==", "funding": [ { "type": "GitHub Sponsors", @@ -10037,14 +9210,13 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "node_modules/micromark-util-normalize-identifier/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -10054,12 +9226,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-resolve-all": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.0.tgz", - "integrity": "sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==", "funding": [ { "type": "GitHub Sponsors", @@ -10070,14 +9241,13 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-types": "^2.0.0" } }, "node_modules/micromark-util-sanitize-uri": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.0.tgz", - "integrity": "sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==", "funding": [ { "type": "GitHub Sponsors", @@ -10088,6 +9258,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", @@ -10096,8 +9267,6 @@ }, "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10108,6 +9277,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -10115,8 +9285,6 @@ }, "node_modules/micromark-util-sanitize-uri/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -10126,12 +9294,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-subtokenize": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.0.0.tgz", - "integrity": "sha512-vc93L1t+gpR3p8jxeVdaYlbV2jTYteDje19rNSS/H5dlhxUYll5Fy6vJ2cDwP8RnsXi818yGty1ayP55y3W6fg==", "funding": [ { "type": "GitHub Sponsors", @@ -10142,6 +9309,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", @@ -10151,8 +9319,6 @@ }, "node_modules/micromark-util-subtokenize/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -10162,12 +9328,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-symbol": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", "funding": [ { "type": "GitHub Sponsors", @@ -10177,12 +9342,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark-util-types": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.0.tgz", - "integrity": "sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==", "funding": [ { "type": "GitHub Sponsors", @@ -10192,12 +9356,11 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromark/node_modules/micromark-factory-space": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.0.tgz", - "integrity": "sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==", "funding": [ { "type": "GitHub Sponsors", @@ -10208,6 +9371,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -10215,8 +9379,6 @@ }, "node_modules/micromark/node_modules/micromark-util-character": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.0.tgz", - "integrity": "sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==", "funding": [ { "type": "GitHub Sponsors", @@ -10227,6 +9389,7 @@ "url": "https://opencollective.com/unified" } ], + "license": "MIT", "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" @@ -10234,8 +9397,6 @@ }, "node_modules/micromark/node_modules/micromark-util-symbol": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.0.tgz", - "integrity": "sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==", "funding": [ { "type": "GitHub Sponsors", @@ -10245,12 +9406,12 @@ "type": "OpenCollective", "url": "https://opencollective.com/unified" } - ] + ], + "license": "MIT" }, "node_modules/micromatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "license": "MIT", "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -10261,8 +9422,7 @@ }, "node_modules/mime": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", "bin": { "mime": "cli.js" }, @@ -10272,16 +9432,14 @@ }, "node_modules/mime-db": { "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "license": "MIT", "dependencies": { "mime-db": "~1.33.0" }, @@ -10291,16 +9449,14 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/mimic-response": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, @@ -10310,8 +9466,7 @@ }, "node_modules/mini-css-extract-plugin": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.8.0.tgz", - "integrity": "sha512-CxmUYPFcTgET1zImteG/LZOy/4T5rTojesQXkSNBiquhydn78tfbCE9sjIjnJ/UcjNjOC1bphTCCW5rrS7cXAg==", + "license": "MIT", "dependencies": { "schema-utils": "^4.0.0", "tapable": "^2.2.1" @@ -10329,13 +9484,11 @@ }, "node_modules/minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + "license": "ISC" }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -10345,29 +9498,25 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/mrmime": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", - "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/ms": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "license": "MIT" }, "node_modules/multicast-dns": { "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "license": "MIT", "dependencies": { "dns-packet": "^5.2.2", "thunky": "^1.0.2" @@ -10378,14 +9527,13 @@ }, "node_modules/nanoid": { "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -10395,21 +9543,18 @@ }, "node_modules/negotiator": { "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/neo-async": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + "license": "MIT" }, "node_modules/no-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "license": "MIT", "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" @@ -10417,8 +9562,7 @@ }, "node_modules/node-emoji": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz", - "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==", + "license": "MIT", "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", @@ -10431,37 +9575,32 @@ }, "node_modules/node-forge": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { "node": ">= 6.13.0" } }, "node_modules/node-releases": { "version": "2.0.14", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", - "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-range": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/normalize-url": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -10471,8 +9610,7 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -10482,13 +9620,11 @@ }, "node_modules/nprogress": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz", - "integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==" + "license": "MIT" }, "node_modules/nth-check": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0" }, @@ -10498,32 +9634,28 @@ }, "node_modules/object-assign": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/object-inspect": { "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-keys": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/object.assign": { "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.5", "define-properties": "^1.2.1", @@ -10539,13 +9671,11 @@ }, "node_modules/obuf": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==" + "license": "MIT" }, "node_modules/on-finished": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { "ee-first": "1.1.1" }, @@ -10555,24 +9685,21 @@ }, "node_modules/on-headers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", "dependencies": { "wrappy": "1" } }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -10585,8 +9712,7 @@ }, "node_modules/open": { "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", + "license": "MIT", "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", @@ -10601,24 +9727,21 @@ }, "node_modules/opener": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "license": "(WTFPL OR MIT)", "bin": { "opener": "bin/opener-bin.js" } }, "node_modules/p-cancelable": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", + "license": "MIT", "engines": { "node": ">=12.20" } }, "node_modules/p-limit": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "license": "MIT", "dependencies": { "yocto-queue": "^1.0.0" }, @@ -10631,8 +9754,7 @@ }, "node_modules/p-locate": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", - "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "license": "MIT", "dependencies": { "p-limit": "^4.0.0" }, @@ -10645,8 +9767,7 @@ }, "node_modules/p-map": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "license": "MIT", "dependencies": { "aggregate-error": "^3.0.0" }, @@ -10659,8 +9780,7 @@ }, "node_modules/p-retry": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", - "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", "dependencies": { "@types/retry": "0.12.0", "retry": "^0.13.1" @@ -10671,16 +9791,14 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/package-json": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", + "license": "MIT", "dependencies": { "got": "^12.1.0", "registry-auth-token": "^5.0.1", @@ -10696,8 +9814,7 @@ }, "node_modules/param-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "license": "MIT", "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" @@ -10705,8 +9822,7 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -10716,8 +9832,7 @@ }, "node_modules/parse-entities": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", + "license": "MIT", "dependencies": { "@types/unist": "^2.0.0", "character-entities": "^2.0.0", @@ -10735,13 +9850,11 @@ }, "node_modules/parse-entities/node_modules/@types/unist": { "version": "2.0.10", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" + "license": "MIT" }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -10757,13 +9870,11 @@ }, "node_modules/parse-numeric-range": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", - "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" + "license": "ISC" }, "node_modules/parse5": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "license": "MIT", "dependencies": { "entities": "^4.4.0" }, @@ -10773,8 +9884,7 @@ }, "node_modules/parse5-htmlparser2-tree-adapter": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz", - "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==", + "license": "MIT", "dependencies": { "domhandler": "^5.0.2", "parse5": "^7.0.0" @@ -10785,16 +9895,14 @@ }, "node_modules/parseurl": { "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/pascal-case": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "license": "MIT", "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" @@ -10802,58 +9910,50 @@ }, "node_modules/path-exists": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", - "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "license": "MIT", "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/path-is-inside": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" + "license": "(WTFPL OR MIT)" }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "license": "MIT" }, "node_modules/path-to-regexp": { "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "license": "MIT", "dependencies": { "isarray": "0.0.1" } }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/periscopic": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "license": "MIT", "dependencies": { "@types/estree": "^1.0.0", "estree-walker": "^3.0.0", @@ -10862,13 +9962,11 @@ }, "node_modules/picocolors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -10878,8 +9976,7 @@ }, "node_modules/pkg-dir": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", - "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "license": "MIT", "dependencies": { "find-up": "^6.3.0" }, @@ -10892,8 +9989,7 @@ }, "node_modules/pkg-up": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "license": "MIT", "dependencies": { "find-up": "^3.0.0" }, @@ -10903,8 +9999,7 @@ }, "node_modules/pkg-up/node_modules/find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "license": "MIT", "dependencies": { "locate-path": "^3.0.0" }, @@ -10914,8 +10009,7 @@ }, "node_modules/pkg-up/node_modules/locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "license": "MIT", "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -10926,8 +10020,7 @@ }, "node_modules/pkg-up/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -10940,8 +10033,7 @@ }, "node_modules/pkg-up/node_modules/p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "license": "MIT", "dependencies": { "p-limit": "^2.0.0" }, @@ -10951,16 +10043,13 @@ }, "node_modules/pkg-up/node_modules/path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/postcss": { "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "funding": [ { "type": "opencollective", @@ -10975,6 +10064,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", @@ -10986,8 +10076,7 @@ }, "node_modules/postcss-calc": { "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.9", "postcss-value-parser": "^4.2.0" @@ -10998,8 +10087,7 @@ }, "node_modules/postcss-colormin": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.1.tgz", - "integrity": "sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", @@ -11015,8 +10103,7 @@ }, "node_modules/postcss-convert-values": { "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz", - "integrity": "sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" @@ -11030,8 +10117,7 @@ }, "node_modules/postcss-discard-comments": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz", - "integrity": "sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11041,8 +10127,7 @@ }, "node_modules/postcss-discard-duplicates": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11052,8 +10137,7 @@ }, "node_modules/postcss-discard-empty": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11063,8 +10147,7 @@ }, "node_modules/postcss-discard-overridden": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11074,8 +10157,7 @@ }, "node_modules/postcss-discard-unused": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-5.1.0.tgz", - "integrity": "sha512-KwLWymI9hbwXmJa0dkrzpRbSJEh0vVUd7r8t0yOGPcfKzyJJxFM8kLyC5Ev9avji6nY95pOp1W6HqIrfT+0VGw==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -11088,8 +10170,7 @@ }, "node_modules/postcss-loader": { "version": "7.3.4", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-7.3.4.tgz", - "integrity": "sha512-iW5WTTBSC5BfsBJ9daFMPVrLT36MrNiC6fqOZTTaHjBNX6Pfd5p+hSBqe/fEeNd7pc13QiAyGt7VdGMw4eRC4A==", + "license": "MIT", "dependencies": { "cosmiconfig": "^8.3.5", "jiti": "^1.20.0", @@ -11109,8 +10190,7 @@ }, "node_modules/postcss-loader/node_modules/cosmiconfig": { "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "license": "MIT", "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", @@ -11134,8 +10214,7 @@ }, "node_modules/postcss-merge-idents": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-5.1.1.tgz", - "integrity": "sha512-pCijL1TREiCoog5nQp7wUe+TUonA2tC2sQ54UGeMmryK3UFGIYKqDyjnqd6RcuI4znFn9hWSLNN8xKE/vWcUQw==", + "license": "MIT", "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" @@ -11149,8 +10228,7 @@ }, "node_modules/postcss-merge-longhand": { "version": "5.1.7", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz", - "integrity": "sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", "stylehacks": "^5.1.1" @@ -11164,8 +10242,7 @@ }, "node_modules/postcss-merge-rules": { "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz", - "integrity": "sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0", @@ -11181,8 +10258,7 @@ }, "node_modules/postcss-minify-font-values": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11195,8 +10271,7 @@ }, "node_modules/postcss-minify-gradients": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "license": "MIT", "dependencies": { "colord": "^2.9.1", "cssnano-utils": "^3.1.0", @@ -11211,8 +10286,7 @@ }, "node_modules/postcss-minify-params": { "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz", - "integrity": "sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "cssnano-utils": "^3.1.0", @@ -11227,8 +10301,7 @@ }, "node_modules/postcss-minify-selectors": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz", - "integrity": "sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -11241,8 +10314,7 @@ }, "node_modules/postcss-modules-extract-imports": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "license": "ISC", "engines": { "node": "^10 || ^12 || >= 14" }, @@ -11252,8 +10324,7 @@ }, "node_modules/postcss-modules-local-by-default": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.4.tgz", - "integrity": "sha512-L4QzMnOdVwRm1Qb8m4x8jsZzKAaPAgrUF1r/hjDR2Xj7R+8Zsf97jAlSQzWtKx5YNiNGN8QxmPFIc/sh+RQl+Q==", + "license": "MIT", "dependencies": { "icss-utils": "^5.0.0", "postcss-selector-parser": "^6.0.2", @@ -11268,8 +10339,7 @@ }, "node_modules/postcss-modules-scope": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.1.1.tgz", - "integrity": "sha512-uZgqzdTleelWjzJY+Fhti6F3C9iF1JR/dODLs/JDefozYcKTBCdD8BIl6nNPbTbcLnGrk56hzwZC2DaGNvYjzA==", + "license": "ISC", "dependencies": { "postcss-selector-parser": "^6.0.4" }, @@ -11282,8 +10352,7 @@ }, "node_modules/postcss-modules-values": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "license": "ISC", "dependencies": { "icss-utils": "^5.0.0" }, @@ -11296,8 +10365,7 @@ }, "node_modules/postcss-normalize-charset": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11307,8 +10375,7 @@ }, "node_modules/postcss-normalize-display-values": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11321,8 +10388,7 @@ }, "node_modules/postcss-normalize-positions": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz", - "integrity": "sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11335,8 +10401,7 @@ }, "node_modules/postcss-normalize-repeat-style": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz", - "integrity": "sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11349,8 +10414,7 @@ }, "node_modules/postcss-normalize-string": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11363,8 +10427,7 @@ }, "node_modules/postcss-normalize-timing-functions": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11377,8 +10440,7 @@ }, "node_modules/postcss-normalize-unicode": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz", - "integrity": "sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "postcss-value-parser": "^4.2.0" @@ -11392,8 +10454,7 @@ }, "node_modules/postcss-normalize-url": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "license": "MIT", "dependencies": { "normalize-url": "^6.0.1", "postcss-value-parser": "^4.2.0" @@ -11407,8 +10468,7 @@ }, "node_modules/postcss-normalize-whitespace": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11421,8 +10481,7 @@ }, "node_modules/postcss-ordered-values": { "version": "5.1.3", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz", - "integrity": "sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==", + "license": "MIT", "dependencies": { "cssnano-utils": "^3.1.0", "postcss-value-parser": "^4.2.0" @@ -11436,8 +10495,7 @@ }, "node_modules/postcss-reduce-idents": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-5.2.0.tgz", - "integrity": "sha512-BTrLjICoSB6gxbc58D5mdBK8OhXRDqud/zodYfdSi52qvDHdMwk+9kB9xsM8yJThH/sZU5A6QVSmMmaN001gIg==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11450,8 +10508,7 @@ }, "node_modules/postcss-reduce-initial": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz", - "integrity": "sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "caniuse-api": "^3.0.0" @@ -11465,8 +10522,7 @@ }, "node_modules/postcss-reduce-transforms": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0" }, @@ -11479,8 +10535,7 @@ }, "node_modules/postcss-selector-parser": { "version": "6.0.15", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz", - "integrity": "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw==", + "license": "MIT", "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -11491,8 +10546,7 @@ }, "node_modules/postcss-sort-media-queries": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/postcss-sort-media-queries/-/postcss-sort-media-queries-4.4.1.tgz", - "integrity": "sha512-QDESFzDDGKgpiIh4GYXsSy6sek2yAwQx1JASl5AxBtU1Lq2JfKBljIPNdil989NcSKRQX1ToiaKphImtBuhXWw==", + "license": "MIT", "dependencies": { "sort-css-media-queries": "2.1.0" }, @@ -11505,8 +10559,7 @@ }, "node_modules/postcss-svgo": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "license": "MIT", "dependencies": { "postcss-value-parser": "^4.2.0", "svgo": "^2.7.0" @@ -11520,8 +10573,7 @@ }, "node_modules/postcss-unique-selectors": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.5" }, @@ -11534,13 +10586,11 @@ }, "node_modules/postcss-value-parser": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==" + "license": "MIT" }, "node_modules/postcss-zindex": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-5.1.0.tgz", - "integrity": "sha512-fgFMf0OtVSBR1va1JNHYgMxYk73yhn/qb4uQDq1DLGYolz8gHCyr/sesEuGUaYs58E3ZJRcpoGuPVoB7Meiq9A==", + "license": "MIT", "engines": { "node": "^10 || ^12 || >=14.0" }, @@ -11550,8 +10600,7 @@ }, "node_modules/pretty-error": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "license": "MIT", "dependencies": { "lodash": "^4.17.20", "renderkid": "^3.0.0" @@ -11559,16 +10608,14 @@ }, "node_modules/pretty-time": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pretty-time/-/pretty-time-1.1.0.tgz", - "integrity": "sha512-28iF6xPQrP8Oa6uxE6a1biz+lWeTOAPKggvjB8HAs6nVMKZwf5bG++632Dx614hIWgUPkgivRfG+a8uAXGTIbA==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/prism-react-renderer": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-2.3.1.tgz", - "integrity": "sha512-Rdf+HzBLR7KYjzpJ1rSoxT9ioO85nZngQEoFIhL07XhtJHlCU3SOz0GJ6+qvMyQe0Se+BV3qpe6Yd/NmQF5Juw==", + "license": "MIT", "dependencies": { "@types/prismjs": "^1.26.0", "clsx": "^2.0.0" @@ -11579,21 +10626,18 @@ }, "node_modules/prismjs": { "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + "license": "MIT" }, "node_modules/prompts": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -11604,8 +10648,7 @@ }, "node_modules/prop-types": { "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -11614,8 +10657,7 @@ }, "node_modules/property-information": { "version": "6.4.1", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.4.1.tgz", - "integrity": "sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -11623,13 +10665,11 @@ }, "node_modules/proto-list": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==" + "license": "ISC" }, "node_modules/proxy-addr": { "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -11640,21 +10680,18 @@ }, "node_modules/proxy-addr/node_modules/ipaddr.js": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/punycode": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" + "license": "MIT" }, "node_modules/pupa": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pupa/-/pupa-3.1.0.tgz", - "integrity": "sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==", + "license": "MIT", "dependencies": { "escape-goat": "^4.0.0" }, @@ -11667,8 +10704,7 @@ }, "node_modules/qs": { "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.4" }, @@ -11681,16 +10717,13 @@ }, "node_modules/queue": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", - "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "license": "MIT", "dependencies": { "inherits": "~2.0.3" } }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "funding": [ { "type": "github", @@ -11704,12 +10737,12 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/quick-lru": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -11719,24 +10752,21 @@ }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, "node_modules/range-parser": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/raw-body": { "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -11749,16 +10779,14 @@ }, "node_modules/raw-body/node_modules/bytes": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", @@ -11771,16 +10799,14 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/react": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" }, @@ -11790,8 +10816,7 @@ }, "node_modules/react-dev-utils": { "version": "12.0.1", - "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-12.0.1.tgz", - "integrity": "sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==", + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.16.0", "address": "^1.1.2", @@ -11824,8 +10849,7 @@ }, "node_modules/react-dev-utils/node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -11839,16 +10863,14 @@ }, "node_modules/react-dev-utils/node_modules/loader-utils": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.2.1.tgz", - "integrity": "sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==", + "license": "MIT", "engines": { "node": ">= 12.13.0" } }, "node_modules/react-dev-utils/node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -11861,8 +10883,7 @@ }, "node_modules/react-dev-utils/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -11875,8 +10896,7 @@ }, "node_modules/react-dev-utils/node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -11889,16 +10909,14 @@ }, "node_modules/react-dev-utils/node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/react-dev-utils/node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", "engines": { "node": ">=10" }, @@ -11908,8 +10926,7 @@ }, "node_modules/react-dom": { "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" @@ -11920,18 +10937,15 @@ }, "node_modules/react-error-overlay": { "version": "6.0.11", - "resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz", - "integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg==" + "license": "MIT" }, "node_modules/react-fast-compare": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz", - "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==" + "license": "MIT" }, "node_modules/react-helmet-async": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/react-helmet-async/-/react-helmet-async-1.3.0.tgz", - "integrity": "sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==", + "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.12.5", "invariant": "^2.2.4", @@ -11946,13 +10960,11 @@ }, "node_modules/react-is": { "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "license": "MIT" }, "node_modules/react-json-view-lite": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/react-json-view-lite/-/react-json-view-lite-1.2.1.tgz", - "integrity": "sha512-Itc0g86fytOmKZoIoJyGgvNqohWSbh3NXIKNgH6W6FT9PC1ck4xas1tT3Rr/b3UlFXyA9Jjaw9QSXdZy2JwGMQ==", + "license": "MIT", "engines": { "node": ">=14" }, @@ -11963,8 +10975,7 @@ "node_modules/react-loadable": { "name": "@docusaurus/react-loadable", "version": "5.5.2", - "resolved": "https://registry.npmjs.org/@docusaurus/react-loadable/-/react-loadable-5.5.2.tgz", - "integrity": "sha512-A3dYjdBGuy0IGT+wyLIGIKLRE+sAk1iNk0f1HjNDysO7u8lhL4N3VEm+FAubmJbAztn94F7MxBTPmnixbiyFdQ==", + "license": "MIT", "dependencies": { "@types/react": "*", "prop-types": "^15.6.2" @@ -11975,8 +10986,7 @@ }, "node_modules/react-loadable-ssr-addon-v5-slorber": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/react-loadable-ssr-addon-v5-slorber/-/react-loadable-ssr-addon-v5-slorber-1.0.1.tgz", - "integrity": "sha512-lq3Lyw1lGku8zUEJPDxsNm1AfYHBrO9Y1+olAYwpUJ2IGFBskM0DMKok97A6LWUpHm+o7IvQBOWu9MLenp9Z+A==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.10.3" }, @@ -11990,8 +11000,7 @@ }, "node_modules/react-router": { "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.3.4.tgz", - "integrity": "sha512-Ys9K+ppnJah3QuaRiLxk+jDWOR1MekYQrlytiXxC1RyfbdsZkS5pvKAzCCr031xHixZwpnsYNT5xysdFHQaYsA==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -12009,8 +11018,7 @@ }, "node_modules/react-router-config": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/react-router-config/-/react-router-config-5.1.1.tgz", - "integrity": "sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.1.2" }, @@ -12021,8 +11029,7 @@ }, "node_modules/react-router-dom": { "version": "5.3.4", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.4.tgz", - "integrity": "sha512-m4EqFMHv/Ih4kpcBCONHbkT68KoAeHN4p3lAGoNryfHi0dMy0kCzEZakiKRsvg5wHZ/JLrLW8o8KomWiz/qbYQ==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.12.13", "history": "^4.9.0", @@ -12038,8 +11045,7 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -12051,8 +11057,7 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", "dependencies": { "picomatch": "^2.2.1" }, @@ -12062,13 +11067,10 @@ }, "node_modules/reading-time": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", - "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" + "license": "MIT" }, "node_modules/rechoir": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", "dependencies": { "resolve": "^1.1.6" }, @@ -12078,8 +11080,7 @@ }, "node_modules/recursive-readdir": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "license": "MIT", "dependencies": { "minimatch": "^3.0.5" }, @@ -12089,13 +11090,11 @@ }, "node_modules/regenerate": { "version": "1.4.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", - "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==" + "license": "MIT" }, "node_modules/regenerate-unicode-properties": { "version": "10.1.1", - "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz", - "integrity": "sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==", + "license": "MIT", "dependencies": { "regenerate": "^1.4.2" }, @@ -12105,21 +11104,18 @@ }, "node_modules/regenerator-runtime": { "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + "license": "MIT" }, "node_modules/regenerator-transform": { "version": "0.15.2", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.2.tgz", - "integrity": "sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==", + "license": "MIT", "dependencies": { "@babel/runtime": "^7.8.4" } }, "node_modules/regexpu-core": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.3.2.tgz", - "integrity": "sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==", + "license": "MIT", "dependencies": { "@babel/regjsgen": "^0.8.0", "regenerate": "^1.4.2", @@ -12134,8 +11130,7 @@ }, "node_modules/registry-auth-token": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz", - "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==", + "license": "MIT", "dependencies": { "@pnpm/npm-conf": "^2.1.0" }, @@ -12145,8 +11140,7 @@ }, "node_modules/registry-url": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "license": "MIT", "dependencies": { "rc": "1.2.8" }, @@ -12159,8 +11153,7 @@ }, "node_modules/regjsparser": { "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "license": "BSD-2-Clause", "dependencies": { "jsesc": "~0.5.0" }, @@ -12170,16 +11163,13 @@ }, "node_modules/regjsparser/node_modules/jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "bin": { "jsesc": "bin/jsesc" } }, "node_modules/rehype-raw": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", - "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "hast-util-raw": "^9.0.0", @@ -12192,16 +11182,14 @@ }, "node_modules/relateurl": { "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, "node_modules/remark-directive": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.0.tgz", - "integrity": "sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-directive": "^3.0.0", @@ -12215,8 +11203,7 @@ }, "node_modules/remark-emoji": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-emoji/-/remark-emoji-4.0.1.tgz", - "integrity": "sha512-fHdvsTR1dHkWKev9eNyhTo4EFwbUvJ8ka9SgeWkMPYFX4WoI7ViVBms3PjlQYgw5TLvNQso3GUB/b/8t3yo+dg==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.2", "emoticon": "^4.0.1", @@ -12230,8 +11217,7 @@ }, "node_modules/remark-frontmatter": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-5.0.0.tgz", - "integrity": "sha512-XTFYvNASMe5iPN0719nPrdItC9aU0ssC4v14mH1BCi1u0n1gAocqcujWUrByftZTbLhRtiKRyjYTSIOcr69UVQ==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-frontmatter": "^2.0.0", @@ -12245,8 +11231,7 @@ }, "node_modules/remark-gfm": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", - "integrity": "sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", @@ -12262,8 +11247,7 @@ }, "node_modules/remark-mdx": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.0.1.tgz", - "integrity": "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==", + "license": "MIT", "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" @@ -12275,8 +11259,7 @@ }, "node_modules/remark-parse": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", - "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", @@ -12290,8 +11273,7 @@ }, "node_modules/remark-rehype": { "version": "11.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.0.tgz", - "integrity": "sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==", + "license": "MIT", "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", @@ -12306,8 +11288,7 @@ }, "node_modules/remark-stringify": { "version": "11.0.0", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", - "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", @@ -12320,8 +11301,7 @@ }, "node_modules/renderkid": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "license": "MIT", "dependencies": { "css-select": "^4.1.3", "dom-converter": "^0.2.0", @@ -12332,8 +11312,7 @@ }, "node_modules/renderkid/node_modules/css-select": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -12347,8 +11326,7 @@ }, "node_modules/renderkid/node_modules/dom-serializer": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -12360,8 +11338,7 @@ }, "node_modules/renderkid/node_modules/domhandler": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" }, @@ -12374,8 +11351,7 @@ }, "node_modules/renderkid/node_modules/domutils": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -12387,16 +11363,13 @@ }, "node_modules/renderkid/node_modules/entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/renderkid/node_modules/htmlparser2": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -12404,6 +11377,7 @@ "url": "https://github.com/sponsors/fb55" } ], + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.0.0", @@ -12413,29 +11387,24 @@ }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/require-like": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", "engines": { "node": "*" } }, "node_modules/requires-port": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -12450,26 +11419,22 @@ }, "node_modules/resolve-alpn": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" + "license": "MIT" }, "node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/resolve-pathname": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + "license": "MIT" }, "node_modules/responselike": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", + "license": "MIT", "dependencies": { "lowercase-keys": "^3.0.0" }, @@ -12482,16 +11447,14 @@ }, "node_modules/retry": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/reusify": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -12499,8 +11462,7 @@ }, "node_modules/rimraf": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "license": "ISC", "dependencies": { "glob": "^7.1.3" }, @@ -12513,13 +11475,11 @@ }, "node_modules/rtl-detect": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/rtl-detect/-/rtl-detect-1.1.2.tgz", - "integrity": "sha512-PGMBq03+TTG/p/cRB7HCLKJ1MgDIi07+QU1faSjiYRfmY5UsAttV9Hs08jDAHVwcOwmVLcSJkpwyfXszVjWfIQ==" + "license": "BSD-3-Clause" }, "node_modules/rtlcss": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/rtlcss/-/rtlcss-4.1.1.tgz", - "integrity": "sha512-/oVHgBtnPNcggP2aVXQjSy6N1mMAfHg4GSag0QtZBlD5bdDgAHwr4pydqJGd+SUCu9260+Pjqbjwtvu7EMH1KQ==", + "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0", @@ -12535,8 +11495,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "funding": [ { "type": "github", @@ -12551,14 +11509,13 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "funding": [ { "type": "github", @@ -12572,30 +11529,27 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "license": "MIT" }, "node_modules/sax": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.3.0.tgz", - "integrity": "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==" + "license": "ISC" }, "node_modules/scheduler": { "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "license": "MIT", "dependencies": { "loose-envify": "^1.1.0" } }, "node_modules/schema-utils": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz", - "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", @@ -12612,14 +11566,12 @@ }, "node_modules/search-insights": { "version": "2.13.0", - "resolved": "https://registry.npmjs.org/search-insights/-/search-insights-2.13.0.tgz", - "integrity": "sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==", + "license": "MIT", "peer": true }, "node_modules/section-matter": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" @@ -12630,13 +11582,11 @@ }, "node_modules/select-hose": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==" + "license": "MIT" }, "node_modules/selfsigned": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", - "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "license": "MIT", "dependencies": { "@types/node-forge": "^1.3.0", "node-forge": "^1" @@ -12647,8 +11597,7 @@ }, "node_modules/semver": { "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "license": "ISC", "dependencies": { "lru-cache": "^6.0.0" }, @@ -12661,8 +11610,7 @@ }, "node_modules/semver-diff": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz", - "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==", + "license": "MIT", "dependencies": { "semver": "^7.3.5" }, @@ -12675,8 +11623,7 @@ }, "node_modules/semver/node_modules/lru-cache": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "license": "ISC", "dependencies": { "yallist": "^4.0.0" }, @@ -12686,13 +11633,11 @@ }, "node_modules/semver/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "license": "ISC" }, "node_modules/send": { "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", @@ -12714,42 +11659,36 @@ }, "node_modules/send/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/send/node_modules/debug/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/send/node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + "license": "MIT" }, "node_modules/send/node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serialize-javascript": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "license": "BSD-3-Clause", "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/serve-handler": { "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", + "license": "MIT", "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", @@ -12763,13 +11702,11 @@ }, "node_modules/serve-handler/node_modules/path-to-regexp": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" + "license": "MIT" }, "node_modules/serve-index": { "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "license": "MIT", "dependencies": { "accepts": "~1.3.4", "batch": "0.6.1", @@ -12785,24 +11722,21 @@ }, "node_modules/serve-index/node_modules/debug": { "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } }, "node_modules/serve-index/node_modules/depd": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-index/node_modules/http-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "license": "MIT", "dependencies": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -12815,31 +11749,26 @@ }, "node_modules/serve-index/node_modules/inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" + "license": "ISC" }, "node_modules/serve-index/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "license": "MIT" }, "node_modules/serve-index/node_modules/setprototypeof": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "license": "ISC" }, "node_modules/serve-index/node_modules/statuses": { "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/serve-static": { "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "license": "MIT", "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", @@ -12852,8 +11781,7 @@ }, "node_modules/set-function-length": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.2", "es-errors": "^1.3.0", @@ -12868,13 +11796,11 @@ }, "node_modules/setprototypeof": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "license": "ISC" }, "node_modules/shallow-clone": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "license": "MIT", "dependencies": { "kind-of": "^6.0.2" }, @@ -12884,13 +11810,11 @@ }, "node_modules/shallowequal": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -12900,24 +11824,21 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/shell-quote": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/shelljs": { "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "license": "BSD-3-Clause", "dependencies": { "glob": "^7.0.0", "interpret": "^1.0.0", @@ -12932,8 +11853,7 @@ }, "node_modules/side-channel": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.5.tgz", - "integrity": "sha512-QcgiIWV4WV7qWExbN5llt6frQB/lBven9pqliLXfGPB+K9ZYXxDozp0wLkHS24kWCm+6YXH/f0HhnObZnZOBnQ==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.6", "es-errors": "^1.3.0", @@ -12949,13 +11869,11 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "license": "ISC" }, "node_modules/sirv": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-2.0.4.tgz", - "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "license": "MIT", "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", @@ -12967,13 +11885,11 @@ }, "node_modules/sisteransi": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + "license": "MIT" }, "node_modules/sitemap": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", - "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "license": "MIT", "dependencies": { "@types/node": "^17.0.5", "@types/sax": "^1.2.1", @@ -12990,13 +11906,11 @@ }, "node_modules/sitemap/node_modules/@types/node": { "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" + "license": "MIT" }, "node_modules/skin-tone": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz", - "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==", + "license": "MIT", "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" }, @@ -13006,16 +11920,14 @@ }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/sockjs": { "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "license": "MIT", "dependencies": { "faye-websocket": "^0.11.3", "uuid": "^8.3.2", @@ -13024,32 +11936,28 @@ }, "node_modules/sort-css-media-queries": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz", - "integrity": "sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==", + "license": "MIT", "engines": { "node": ">= 6.3.0" } }, "node_modules/source-map": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } }, "node_modules/source-map-js": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/source-map-support": { "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -13057,16 +11965,14 @@ }, "node_modules/source-map-support/node_modules/source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/space-separated-tokens": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -13074,8 +11980,7 @@ }, "node_modules/spdy": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "license": "MIT", "dependencies": { "debug": "^4.1.0", "handle-thing": "^2.0.0", @@ -13089,8 +11994,7 @@ }, "node_modules/spdy-transport": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "license": "MIT", "dependencies": { "debug": "^4.1.0", "detect-node": "^2.0.4", @@ -13102,13 +12006,11 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "license": "BSD-3-Clause" }, "node_modules/srcset": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/srcset/-/srcset-4.0.0.tgz", - "integrity": "sha512-wvLeHgcVHKO8Sc/H/5lkGreJQVeYMm9rlmt8PuR1xE31rIuXhuzznUUqAt8MqLhB3MqJdFzlNAfpcWnxiFUcPw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -13118,35 +12020,29 @@ }, "node_modules/stable": { "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" + "license": "MIT" }, "node_modules/statuses": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/std-env": { "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==" + "license": "MIT" }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" } }, "node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", @@ -13161,8 +12057,7 @@ }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -13172,8 +12067,7 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -13186,8 +12080,7 @@ }, "node_modules/stringify-entities": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "license": "MIT", "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" @@ -13199,8 +12092,7 @@ }, "node_modules/stringify-object": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "license": "BSD-2-Clause", "dependencies": { "get-own-enumerable-property-symbols": "^3.0.0", "is-obj": "^1.0.1", @@ -13212,8 +12104,7 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -13223,24 +12114,21 @@ }, "node_modules/strip-bom-string": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", "engines": { "node": ">=8" }, @@ -13250,16 +12138,14 @@ }, "node_modules/style-to-object": { "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", + "license": "MIT", "dependencies": { "inline-style-parser": "0.1.1" } }, "node_modules/stylehacks": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.1.tgz", - "integrity": "sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==", + "license": "MIT", "dependencies": { "browserslist": "^4.21.4", "postcss-selector-parser": "^6.0.4" @@ -13273,8 +12159,7 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -13284,8 +12169,7 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -13295,13 +12179,11 @@ }, "node_modules/svg-parser": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz", - "integrity": "sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==" + "license": "MIT" }, "node_modules/svgo": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "license": "MIT", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", @@ -13320,16 +12202,14 @@ }, "node_modules/svgo/node_modules/commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/svgo/node_modules/css-select": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "license": "BSD-2-Clause", "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", @@ -13343,8 +12223,7 @@ }, "node_modules/svgo/node_modules/dom-serializer": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "license": "MIT", "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", @@ -13356,8 +12235,7 @@ }, "node_modules/svgo/node_modules/domhandler": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "license": "BSD-2-Clause", "dependencies": { "domelementtype": "^2.2.0" }, @@ -13370,8 +12248,7 @@ }, "node_modules/svgo/node_modules/domutils": { "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "license": "BSD-2-Clause", "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", @@ -13383,24 +12260,21 @@ }, "node_modules/svgo/node_modules/entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "license": "BSD-2-Clause", "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } }, "node_modules/tapable": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/terser": { "version": "5.27.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.1.tgz", - "integrity": "sha512-29wAr6UU/oQpnTw5HoadwjUZnFQXGdOfj0LjZ4sVxzqwHh/QVkvr7m8y9WoR4iN3FRitVduTc6KdjcW38Npsug==", + "license": "BSD-2-Clause", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -13416,8 +12290,7 @@ }, "node_modules/terser-webpack-plugin": { "version": "5.3.10", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", - "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", @@ -13449,8 +12322,7 @@ }, "node_modules/terser-webpack-plugin/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -13464,16 +12336,14 @@ }, "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/terser-webpack-plugin/node_modules/jest-worker": { "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "license": "MIT", "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", @@ -13485,13 +12355,11 @@ }, "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "license": "MIT" }, "node_modules/terser-webpack-plugin/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -13507,8 +12375,7 @@ }, "node_modules/terser-webpack-plugin/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -13521,41 +12388,34 @@ }, "node_modules/terser/node_modules/commander": { "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + "license": "MIT" }, "node_modules/text-table": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + "license": "MIT" }, "node_modules/thunky": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==" + "license": "MIT" }, "node_modules/tiny-invariant": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", - "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==" + "license": "MIT" }, "node_modules/tiny-warning": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + "license": "MIT" }, "node_modules/to-fast-properties": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -13565,24 +12425,21 @@ }, "node_modules/toidentifier": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", "engines": { "node": ">=0.6" } }, "node_modules/totalist": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", - "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/trim-lines": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -13590,8 +12447,7 @@ }, "node_modules/trough": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", - "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -13599,13 +12455,11 @@ }, "node_modules/tslib": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + "license": "0BSD" }, "node_modules/type-fest": { "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=12.20" }, @@ -13615,8 +12469,7 @@ }, "node_modules/type-is": { "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "license": "MIT", "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" @@ -13627,16 +12480,14 @@ }, "node_modules/type-is/node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/type-is/node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -13646,16 +12497,14 @@ }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "license": "MIT", "dependencies": { "is-typedarray": "^1.0.0" } }, "node_modules/typescript": { "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -13666,29 +12515,25 @@ }, "node_modules/undici-types": { "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", - "integrity": "sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-emoji-modifier-base": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz", - "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-match-property-ecmascript": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", - "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", "dependencies": { "unicode-canonical-property-names-ecmascript": "^2.0.0", "unicode-property-aliases-ecmascript": "^2.0.0" @@ -13699,24 +12544,21 @@ }, "node_modules/unicode-match-property-value-ecmascript": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz", - "integrity": "sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unicode-property-aliases-ecmascript": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", - "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/unified": { "version": "11.0.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.4.tgz", - "integrity": "sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", @@ -13733,8 +12575,7 @@ }, "node_modules/unique-string": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz", - "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==", + "license": "MIT", "dependencies": { "crypto-random-string": "^4.0.0" }, @@ -13747,8 +12588,7 @@ }, "node_modules/unist-util-is": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", - "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -13759,8 +12599,7 @@ }, "node_modules/unist-util-position": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", - "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -13771,8 +12610,7 @@ }, "node_modules/unist-util-position-from-estree": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", - "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -13783,8 +12621,7 @@ }, "node_modules/unist-util-remove-position": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", - "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" @@ -13796,8 +12633,7 @@ }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", - "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0" }, @@ -13808,8 +12644,7 @@ }, "node_modules/unist-util-visit": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", - "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", @@ -13822,8 +12657,7 @@ }, "node_modules/unist-util-visit-parents": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", - "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" @@ -13835,24 +12669,20 @@ }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", "engines": { "node": ">= 10.0.0" } }, "node_modules/unpipe": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/update-browserslist-db": { "version": "1.0.13", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", - "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", "funding": [ { "type": "opencollective", @@ -13867,6 +12697,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" @@ -13880,8 +12711,7 @@ }, "node_modules/update-notifier": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-6.0.2.tgz", - "integrity": "sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==", + "license": "BSD-2-Clause", "dependencies": { "boxen": "^7.0.0", "chalk": "^5.0.1", @@ -13907,8 +12737,7 @@ }, "node_modules/update-notifier/node_modules/boxen": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "license": "MIT", "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^7.0.1", @@ -13928,8 +12757,7 @@ }, "node_modules/update-notifier/node_modules/camelcase": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "license": "MIT", "engines": { "node": ">=14.16" }, @@ -13939,8 +12767,7 @@ }, "node_modules/update-notifier/node_modules/chalk": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, @@ -13950,24 +12777,21 @@ }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, "node_modules/uri-js/node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/url-loader": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "license": "MIT", "dependencies": { "loader-utils": "^2.0.0", "mime-types": "^2.1.27", @@ -13992,8 +12816,7 @@ }, "node_modules/url-loader/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14007,29 +12830,25 @@ }, "node_modules/url-loader/node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/url-loader/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "license": "MIT" }, "node_modules/url-loader/node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/url-loader/node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -14039,8 +12858,7 @@ }, "node_modules/url-loader/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -14056,55 +12874,47 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + "license": "MIT" }, "node_modules/utila": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==" + "license": "MIT" }, "node_modules/utility-types": { "version": "3.11.0", - "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", - "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", "engines": { "node": ">= 4" } }, "node_modules/utils-merge": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", "engines": { "node": ">= 0.4.0" } }, "node_modules/uuid": { "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", "bin": { "uuid": "dist/bin/uuid" } }, "node_modules/value-equal": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + "license": "MIT" }, "node_modules/vary": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, "node_modules/vfile": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.1.tgz", - "integrity": "sha512-1bYqc7pt6NIADBJ98UiG0Bn/CHIVOoZ/IyEkqIruLg0mE1BKzkOXY2D6CSqQIcKqgadppE5lrxgWXJmXd7zZJw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0", @@ -14117,8 +12927,7 @@ }, "node_modules/vfile-location": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.2.tgz", - "integrity": "sha512-NXPYyxyBSH7zB5U6+3uDdd6Nybz6o6/od9rk8bp9H8GR3L+cm/fC0uUTbqBmUTnMCUDslAGBOIKNfvvb+gGlDg==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" @@ -14130,8 +12939,7 @@ }, "node_modules/vfile-message": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", - "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "license": "MIT", "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" @@ -14143,8 +12951,7 @@ }, "node_modules/watchpack": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "license": "MIT", "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" @@ -14155,16 +12962,14 @@ }, "node_modules/wbuf": { "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "license": "MIT", "dependencies": { "minimalistic-assert": "^1.0.0" } }, "node_modules/web-namespaces": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -14172,8 +12977,7 @@ }, "node_modules/webpack": { "version": "5.90.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.90.2.tgz", - "integrity": "sha512-ziXu8ABGr0InCMEYFnHrYweinHK2PWrMqnwdHk2oK3rRhv/1B+2FnfwYv5oD+RrknK/Pp/Hmyvu+eAsaMYhzCw==", + "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.5", @@ -14218,8 +13022,7 @@ }, "node_modules/webpack-bundle-analyzer": { "version": "4.10.1", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.10.1.tgz", - "integrity": "sha512-s3P7pgexgT/HTUSYgxJyn28A+99mmLq4HsJepMPzu0R8ImJc52QNqaFYW1Z2z2uIb1/J3eYgaAWVpaC+v/1aAQ==", + "license": "MIT", "dependencies": { "@discoveryjs/json-ext": "0.5.7", "acorn": "^8.0.4", @@ -14244,16 +13047,14 @@ }, "node_modules/webpack-bundle-analyzer/node_modules/commander": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "license": "MIT", "engines": { "node": ">= 10" } }, "node_modules/webpack-dev-middleware": { "version": "5.3.3", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz", - "integrity": "sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA==", + "license": "MIT", "dependencies": { "colorette": "^2.0.10", "memfs": "^3.4.3", @@ -14274,16 +13075,14 @@ }, "node_modules/webpack-dev-middleware/node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/webpack-dev-middleware/node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -14293,16 +13092,14 @@ }, "node_modules/webpack-dev-middleware/node_modules/range-parser": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/webpack-dev-server": { "version": "4.15.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz", - "integrity": "sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA==", + "license": "MIT", "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -14359,8 +13156,7 @@ }, "node_modules/webpack-dev-server/node_modules/ws": { "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "license": "MIT", "engines": { "node": ">=10.0.0" }, @@ -14379,8 +13175,7 @@ }, "node_modules/webpack-merge": { "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "license": "MIT", "dependencies": { "clone-deep": "^4.0.1", "flat": "^5.0.2", @@ -14392,16 +13187,14 @@ }, "node_modules/webpack-sources": { "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "license": "MIT", "engines": { "node": ">=10.13.0" } }, "node_modules/webpack/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -14415,29 +13208,25 @@ }, "node_modules/webpack/node_modules/ajv-keywords": { "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "license": "MIT", "peerDependencies": { "ajv": "^6.9.1" } }, "node_modules/webpack/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "license": "MIT" }, "node_modules/webpack/node_modules/mime-db": { "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/webpack/node_modules/mime-types": { "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -14447,8 +13236,7 @@ }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "license": "MIT", "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", @@ -14464,8 +13252,7 @@ }, "node_modules/webpackbar": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/webpackbar/-/webpackbar-5.0.2.tgz", - "integrity": "sha512-BmFJo7veBDgQzfWXl/wwYXr/VFus0614qZ8i9znqcl9fnEdiVkdbi0TedLQ6xAK92HZHDJ0QmyQ0fmuZPAgCYQ==", + "license": "MIT", "dependencies": { "chalk": "^4.1.0", "consola": "^2.15.3", @@ -14481,8 +13268,7 @@ }, "node_modules/websocket-driver": { "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", "safe-buffer": ">=5.1.0", @@ -14494,16 +13280,14 @@ }, "node_modules/websocket-extensions": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "license": "Apache-2.0", "engines": { "node": ">=0.8.0" } }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -14516,8 +13300,7 @@ }, "node_modules/widest-line": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "license": "MIT", "dependencies": { "string-width": "^5.0.1" }, @@ -14530,13 +13313,11 @@ }, "node_modules/wildcard": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" + "license": "MIT" }, "node_modules/wrap-ansi": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", @@ -14551,8 +13332,7 @@ }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -14562,8 +13342,7 @@ }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -14573,8 +13352,7 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" }, @@ -14587,13 +13365,11 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", @@ -14603,8 +13379,7 @@ }, "node_modules/ws": { "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "license": "MIT", "engines": { "node": ">=8.3.0" }, @@ -14623,8 +13398,7 @@ }, "node_modules/xdg-basedir": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", - "integrity": "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -14634,8 +13408,7 @@ }, "node_modules/xml-js": { "version": "1.6.11", - "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", - "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "license": "MIT", "dependencies": { "sax": "^1.2.4" }, @@ -14645,21 +13418,18 @@ }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "license": "ISC" }, "node_modules/yaml": { "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "license": "ISC", "engines": { "node": ">= 6" } }, "node_modules/yocto-queue": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "license": "MIT", "engines": { "node": ">=12.20" }, @@ -14669,8 +13439,7 @@ }, "node_modules/zwitch": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" diff --git a/web/docusaurus/src/remark/internalPathnameLinks.ts b/web/docusaurus/src/remark/internalPathnameLinks.ts new file mode 100644 index 00000000..62cd7ff7 --- /dev/null +++ b/web/docusaurus/src/remark/internalPathnameLinks.ts @@ -0,0 +1,324 @@ +import type { Transformer } from "unified"; +import type { Parent } from "unist"; +import type { Link } from "mdast"; +import type { + MdxJsxFlowElement, + MdxjsEsm, + MdxJsxAttributeValueExpression, +} from "mdast-util-mdx"; +import { transformNode } from "@docusaurus/mdx-loader/src/remark/utils"; +import escapeHtml from "escape-html"; +import { visit } from "unist-util-visit"; + +// Transforms links starting with `static://` into elements with `pathname://` and `target={null}`. +// See: https://github.com/facebook/docusaurus/issues/3309#issuecomment-893839723 +// Based on: https://github.com/facebook/docusaurus/blob/caa81e570afd/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts + +const URL_SCHEME = "static://"; + +/* +{ + type: 'link', + title: null, + url: '/docs/api/hexdoc/core/properties.html', + children: [ + { + type: 'text', + value: 'hexdoc.core.properties', + position: [Object] + } + ], + position: { + start: { line: 21, column: 1, offset: 935 }, + end: { line: 21, column: 64, offset: 998 } + } +} + +{ + type: 'link', + title: null, + url: 'pathname:///docs/api/hexdoc/core/properties.html', + children: [ + { + type: 'text', + value: 'hexdoc.core.properties', + position: [Object] + } + ], + position: { + start: { line: 23, column: 1, offset: 1002 }, + end: { line: 23, column: 75, offset: 1076 } + } +} + +{ + type: 'link', + title: null, + url: 'static:///docs/api/hexdoc/core/properties.html', + children: [ + { + type: 'text', + value: 'hexdoc.core.properties', + position: [Object] + } + ], + position: { + start: { line: 25, column: 1, offset: 1080 }, + end: { line: 25, column: 73, offset: 1152 } + } +} + +{ + type: 'mdxJsxFlowElement', + name: 'Link', + attributes: [ + { + type: 'mdxJsxAttribute', + name: 'to', + value: 'pathname:///docs/api/hexdoc/core/properties.html', + position: { + start: { line: 27, column: 7, offset: 1162 }, + end: { line: 27, column: 60, offset: 1215 } + } + }, + { + type: 'mdxJsxAttribute', + name: 'target', + value: { + type: 'mdxJsxAttributeValueExpression', + value: 'null', + data: { + estree: { + type: 'Program', + start: 1224, + end: 1228, + body: [ + { + type: 'ExpressionStatement', + expression: Node { + type: 'Literal', + start: 1224, + end: 1228, + loc: { + start: { line: 27, column: 68, offset: 1224 }, + end: { line: 27, column: 72, offset: 1228 } + }, + value: null, + raw: 'null', + range: [ 1224, 1228 ] + }, + start: 1224, + end: 1228, + loc: { + start: { line: 27, column: 68, offset: 1224 }, + end: { line: 27, column: 72, offset: 1228 } + }, + range: [ 1224, 1228 ] + } + ], + sourceType: 'module', + comments: [], + loc: { + start: { line: 27, column: 68, offset: 1224 }, + end: { line: 27, column: 72, offset: 1228 } + }, + range: [ 1224, 1228 ] + } + } + }, + position: { + start: { line: 27, column: 61, offset: 1216 }, + end: { line: 27, column: 74, offset: 1229 } + } + }, + { + type: 'mdxJsxAttribute', + name: 'rel', + value: { + type: 'mdxJsxAttributeValueExpression', + value: 'null', + data: { + estree: { + type: 'Program', + start: 1235, + end: 1239, + body: [ + { + type: 'ExpressionStatement', + expression: Node { + type: 'Literal', + start: 1235, + end: 1239, + loc: { + start: { line: 27, column: 79, offset: 1235 }, + end: { line: 27, column: 83, offset: 1239 } + }, + value: null, + raw: 'null', + range: [ 1235, 1239 ] + }, + start: 1235, + end: 1239, + loc: { + start: { line: 27, column: 79, offset: 1235 }, + end: { line: 27, column: 83, offset: 1239 } + }, + range: [ 1235, 1239 ] + } + ], + sourceType: 'module', + comments: [], + loc: { + start: { line: 27, column: 79, offset: 1235 }, + end: { line: 27, column: 83, offset: 1239 } + }, + range: [ 1235, 1239 ] + } + } + }, + position: { + start: { line: 27, column: 75, offset: 1230 }, + end: { line: 27, column: 85, offset: 1240 } + } + } + ], + children: [ + { + type: 'text', + value: 'hexdoc.core.properties', + position: { + start: { line: 27, column: 86, offset: 1241 }, + end: { line: 27, column: 108, offset: 1263 } + } + } + ], + position: { + start: { line: 27, column: 1, offset: 1156 }, + end: { line: 27, column: 115, offset: 1270 } + }, + data: { _mdxExplicitJsx: true } +} +*/ + +const nullExpression: MdxJsxAttributeValueExpression = { + type: "mdxJsxAttributeValueExpression", + value: "null", + data: { + estree: { + type: "Program", + sourceType: "module", + body: [ + { + type: "ExpressionStatement", + expression: { + type: "Literal", + value: null, + raw: "null", + }, + }, + ], + }, + }, +}; + +// import foo from "bar"; +function defaultImportNode({ + name, + source, +}: { + name: string; + source: string; +}): MdxjsEsm { + return { + type: "mdxjsEsm", + value: `import ${name} from '${source}';`, + data: { + estree: { + type: "Program", + sourceType: "module", + body: [ + { + type: "ImportDeclaration", + specifiers: [ + { + type: "ImportDefaultSpecifier", + local: { type: "Identifier", name }, + }, + ], + source: { + type: "Literal", + value: source, + raw: `'${source}'`, + }, + }, + ], + }, + }, + }; +} + +function processLinkNode(node: Link) { + if (!node.url.startsWith(URL_SCHEME)) return; + + const strippedUrl = node.url.slice(URL_SCHEME.length); + const newUrl = `pathname://${strippedUrl}`; + + const attributes: MdxJsxFlowElement["attributes"] = []; + + // to=newUrl target={null} rel={null} + attributes.push( + { + type: "mdxJsxAttribute", + name: "to", + value: newUrl, + }, + { + type: "mdxJsxAttribute", + name: "target", + value: nullExpression, + }, + { + type: "mdxJsxAttribute", + name: "rel", + value: nullExpression, + } + ); + + if (node.title) { + attributes.push({ + type: "mdxJsxAttribute", + name: "title", + value: escapeHtml(node.title), + }); + } + + const children = node.children; + + transformNode(node, { + type: "mdxJsxFlowElement", + name: "Link", + attributes, + children, + }); +} + +export default function plugin(): Transformer { + return (tree: Parent) => { + visit(tree, "link", processLinkNode); + + // https://github.com/mrazauskas/docusaurus-remark-plugin-tab-blocks/blob/fb535617b7a3/index.js#L146 + let includesImportLink = false; + + visit(tree, "mdxjsEsm", (node: MdxjsEsm, index, parent) => { + if (node.value.includes("@docusaurus/Link")) { + includesImportLink = true; + } + }); + + if (!includesImportLink) { + tree.children.unshift( + defaultImportNode({ name: "Link", source: "@docusaurus/Link" }) + ); + } + }; +} From 3cc362477671bfcd62066c7192f0bcb8f86b9afc Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 9 May 2024 17:38:26 -0400 Subject: [PATCH 023/106] Document model rendering precedence --- .../04-textures/_model_precedence.md | 13 +++++++ .../docs/03-guides/04-textures/index.md | 36 ++++++++++++++++++ .../01-github-pages.md | 0 .../_category_.yml | 0 .../01-model-rendering/amethyst_sconce.png | Bin .../01-model-rendering/anvil.png | Bin .../01-model-rendering/edified_stairs.png | Bin .../01-model-rendering/index.md | 2 +- .../01-model-rendering/sculk_shrieker.png | Bin .../02-patchouli-schemas.md | 0 .../_category_.yml | 0 11 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 web/docusaurus/docs/03-guides/04-textures/_model_precedence.md create mode 100644 web/docusaurus/docs/03-guides/04-textures/index.md rename web/docusaurus/docs/03-guides/{04-deployment => 05-deployment}/01-github-pages.md (100%) rename web/docusaurus/docs/03-guides/{04-deployment => 05-deployment}/_category_.yml (100%) rename web/docusaurus/docs/03-guides/{05-standalone => 06-standalone}/01-model-rendering/amethyst_sconce.png (100%) rename web/docusaurus/docs/03-guides/{05-standalone => 06-standalone}/01-model-rendering/anvil.png (100%) rename web/docusaurus/docs/03-guides/{05-standalone => 06-standalone}/01-model-rendering/edified_stairs.png (100%) rename web/docusaurus/docs/03-guides/{05-standalone => 06-standalone}/01-model-rendering/index.md (89%) rename web/docusaurus/docs/03-guides/{05-standalone => 06-standalone}/01-model-rendering/sculk_shrieker.png (100%) rename web/docusaurus/docs/03-guides/{05-standalone => 06-standalone}/02-patchouli-schemas.md (100%) rename web/docusaurus/docs/03-guides/{05-standalone => 06-standalone}/_category_.yml (100%) diff --git a/web/docusaurus/docs/03-guides/04-textures/_model_precedence.md b/web/docusaurus/docs/03-guides/04-textures/_model_precedence.md new file mode 100644 index 00000000..c57cd4a0 --- /dev/null +++ b/web/docusaurus/docs/03-guides/04-textures/_model_precedence.md @@ -0,0 +1,13 @@ +import CodeBlock from '@theme/CodeBlock'; + +1. `hexdoc.toml`: + { + `[textures.override.model]\n"${props.namespace}:${props.path}" = ...` + } +2. Internal resources: assets/{props.namespace}/hexdoc/renders/{props.path}.\{png,gif\} + * If multiple formats exist, the one configured in `props.textures.animated.format` (default: APNG) will be used. +3. On-demand model rendering: assets/{props.namespace}/models/{props.path}.json +4. External resources: assets/{props.namespace}/hexdoc/renders/{props.path}.\{png,gif\} diff --git a/web/docusaurus/docs/03-guides/04-textures/index.md b/web/docusaurus/docs/03-guides/04-textures/index.md new file mode 100644 index 00000000..22d05782 --- /dev/null +++ b/web/docusaurus/docs/03-guides/04-textures/index.md @@ -0,0 +1,36 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import ModelPrecedence from "./_model_precedence.md"; + +# Textures + +## Model precedence + +When loading or rendering a model `namespace:path` (eg. `minecraft:item/stick`), the following options will be attempted in this order; the first to successfully load will be used. + + + { + [ + { namespace: "{namespace}", path: "{path}" }, + { namespace: "minecraft", path: "item/stick" }, + ].map((props, i) => { + const { namespace, path } = props; + const key = i == 0 ? "generic" : `example${i}`; + return ( + {namespace}:{path}} + > + + + ); + }) + } + + +:::note + +In hexdoc.toml, if `textures.strict` is `True` (the default) and none of the above options are successfully loaded, the build will fail. + +::: diff --git a/web/docusaurus/docs/03-guides/04-deployment/01-github-pages.md b/web/docusaurus/docs/03-guides/05-deployment/01-github-pages.md similarity index 100% rename from web/docusaurus/docs/03-guides/04-deployment/01-github-pages.md rename to web/docusaurus/docs/03-guides/05-deployment/01-github-pages.md diff --git a/web/docusaurus/docs/03-guides/04-deployment/_category_.yml b/web/docusaurus/docs/03-guides/05-deployment/_category_.yml similarity index 100% rename from web/docusaurus/docs/03-guides/04-deployment/_category_.yml rename to web/docusaurus/docs/03-guides/05-deployment/_category_.yml diff --git a/web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/amethyst_sconce.png b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/amethyst_sconce.png similarity index 100% rename from web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/amethyst_sconce.png rename to web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/amethyst_sconce.png diff --git a/web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/anvil.png b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/anvil.png similarity index 100% rename from web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/anvil.png rename to web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/anvil.png diff --git a/web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/edified_stairs.png b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/edified_stairs.png similarity index 100% rename from web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/edified_stairs.png rename to web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/edified_stairs.png diff --git a/web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/index.md b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.md similarity index 89% rename from web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/index.md rename to web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.md index 34067bba..258b1224 100644 --- a/web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/index.md +++ b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.md @@ -1,6 +1,6 @@ # Model Rendering -hexdoc includes a fairly advanced module for rendering block models. It runs by default when building a web book, but you can also use it as a standalone tool with a bit of configuration. +hexdoc includes a [fairly advanced module](../../textures) for rendering block models. It runs by default when building a web book, but you can also use it as a standalone tool with a bit of configuration. For a complete example, see [examples/model_rendering](https://github.com/hexdoc-dev/hexdoc/tree/main/examples/model_rendering) in hexdoc's GitHub repo. diff --git a/web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/sculk_shrieker.png b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/sculk_shrieker.png similarity index 100% rename from web/docusaurus/docs/03-guides/05-standalone/01-model-rendering/sculk_shrieker.png rename to web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/sculk_shrieker.png diff --git a/web/docusaurus/docs/03-guides/05-standalone/02-patchouli-schemas.md b/web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.md similarity index 100% rename from web/docusaurus/docs/03-guides/05-standalone/02-patchouli-schemas.md rename to web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.md diff --git a/web/docusaurus/docs/03-guides/05-standalone/_category_.yml b/web/docusaurus/docs/03-guides/06-standalone/_category_.yml similarity index 100% rename from web/docusaurus/docs/03-guides/05-standalone/_category_.yml rename to web/docusaurus/docs/03-guides/06-standalone/_category_.yml From 5965d524d76c898a73538000b957e1e29c38205b Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 9 May 2024 17:51:04 -0400 Subject: [PATCH 024/106] Rename all documentation .md files to .mdx, and format with Prettier --- web/docusaurus/.prettierrc | 3 +- .../docs/{01-intro.md => 01-intro.mdx} | 0 .../{01-templates.md => 01-templates.mdx} | 0 ...-configuration.md => 01-configuration.mdx} | 0 ...-custom-styles.md => 02-custom-styles.mdx} | 6 +-- .../03-spoilers/{index.md => index.mdx} | 6 +-- ...el_precedence.md => _model_precedence.mdx} | 16 +++---- .../docs/03-guides/04-textures/index.md | 36 ---------------- .../docs/03-guides/04-textures/index.mdx | 42 +++++++++++++++++++ ...01-github-pages.md => 01-github-pages.mdx} | 6 +-- .../{index.md => index.mdx} | 0 .../06-standalone/02-patchouli-schemas.md | 34 --------------- .../06-standalone/02-patchouli-schemas.mdx | 34 +++++++++++++++ 13 files changed, 94 insertions(+), 89 deletions(-) rename web/docusaurus/docs/{01-intro.md => 01-intro.mdx} (100%) rename web/docusaurus/docs/02-getting-started/{01-templates.md => 01-templates.mdx} (100%) rename web/docusaurus/docs/03-guides/{01-configuration.md => 01-configuration.mdx} (100%) rename web/docusaurus/docs/03-guides/{02-custom-styles.md => 02-custom-styles.mdx} (91%) rename web/docusaurus/docs/03-guides/03-spoilers/{index.md => index.mdx} (94%) rename web/docusaurus/docs/03-guides/04-textures/{_model_precedence.md => _model_precedence.mdx} (55%) delete mode 100644 web/docusaurus/docs/03-guides/04-textures/index.md create mode 100644 web/docusaurus/docs/03-guides/04-textures/index.mdx rename web/docusaurus/docs/03-guides/05-deployment/{01-github-pages.md => 01-github-pages.mdx} (95%) rename web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/{index.md => index.mdx} (100%) delete mode 100644 web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.md create mode 100644 web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.mdx diff --git a/web/docusaurus/.prettierrc b/web/docusaurus/.prettierrc index 1ca87ab7..cc1a6920 100644 --- a/web/docusaurus/.prettierrc +++ b/web/docusaurus/.prettierrc @@ -1,3 +1,4 @@ { - "singleQuote": false + "singleQuote": false, + "experimentalTernaries": false } diff --git a/web/docusaurus/docs/01-intro.md b/web/docusaurus/docs/01-intro.mdx similarity index 100% rename from web/docusaurus/docs/01-intro.md rename to web/docusaurus/docs/01-intro.mdx diff --git a/web/docusaurus/docs/02-getting-started/01-templates.md b/web/docusaurus/docs/02-getting-started/01-templates.mdx similarity index 100% rename from web/docusaurus/docs/02-getting-started/01-templates.md rename to web/docusaurus/docs/02-getting-started/01-templates.mdx diff --git a/web/docusaurus/docs/03-guides/01-configuration.md b/web/docusaurus/docs/03-guides/01-configuration.mdx similarity index 100% rename from web/docusaurus/docs/03-guides/01-configuration.md rename to web/docusaurus/docs/03-guides/01-configuration.mdx diff --git a/web/docusaurus/docs/03-guides/02-custom-styles.md b/web/docusaurus/docs/03-guides/02-custom-styles.mdx similarity index 91% rename from web/docusaurus/docs/03-guides/02-custom-styles.md rename to web/docusaurus/docs/03-guides/02-custom-styles.mdx index 3d827a0f..1f85e35e 100644 --- a/web/docusaurus/docs/03-guides/02-custom-styles.md +++ b/web/docusaurus/docs/03-guides/02-custom-styles.mdx @@ -59,9 +59,9 @@ If you're creating a book for a Hex Casting addon, use `hexcasting:index.css.jin There are two problems with this approach: -* You must specify a namespace (the `hexdoc:` part) to prevent the template from recursively rendering itself. This can be error-prone if you pick the wrong namespace. - * For example, [hexdoc-hexcasting](https://github.com/object-Object/HexMod/blob/7edab68db2bee50285e354f7c9b935b512ebc4bd/doc/src/hexdoc_hexcasting/_templates/index.css.jinja) adds styles to `index.css`, which is why the above note is necessary. -* Your custom styles might interfere with other hexdoc plugins if they add your modid to [`template.include`](static:///docs/api/hexdoc/core/properties.html#TemplateProps.include). +- You must specify a namespace (the `hexdoc:` part) to prevent the template from recursively rendering itself. This can be error-prone if you pick the wrong namespace. + - For example, [hexdoc-hexcasting](https://github.com/object-Object/HexMod/blob/7edab68db2bee50285e354f7c9b935b512ebc4bd/doc/src/hexdoc_hexcasting/_templates/index.css.jinja) adds styles to `index.css`, which is why the above note is necessary. +- Your custom styles might interfere with other hexdoc plugins if they add your modid to [`template.include`](static:///docs/api/hexdoc/core/properties.html#TemplateProps.include). Both of these problems can be avoided by using the `template.extend_render` approach. diff --git a/web/docusaurus/docs/03-guides/03-spoilers/index.md b/web/docusaurus/docs/03-guides/03-spoilers/index.mdx similarity index 94% rename from web/docusaurus/docs/03-guides/03-spoilers/index.md rename to web/docusaurus/docs/03-guides/03-spoilers/index.mdx index 591bdc3b..c25ded67 100644 --- a/web/docusaurus/docs/03-guides/03-spoilers/index.md +++ b/web/docusaurus/docs/03-guides/03-spoilers/index.mdx @@ -10,10 +10,8 @@ To mark an advancement as spoilered, add it to a JSON tag file in the correct lo ```json title="doc/resources/data/hexdoc/tags/advancements/spoilered.json" { - "replace": false, - "values": [ - "minecraft:nether/all_effects" - ] + "replace": false, + "values": ["minecraft:nether/all_effects"] } ``` diff --git a/web/docusaurus/docs/03-guides/04-textures/_model_precedence.md b/web/docusaurus/docs/03-guides/04-textures/_model_precedence.mdx similarity index 55% rename from web/docusaurus/docs/03-guides/04-textures/_model_precedence.md rename to web/docusaurus/docs/03-guides/04-textures/_model_precedence.mdx index c57cd4a0..9f01b7f8 100644 --- a/web/docusaurus/docs/03-guides/04-textures/_model_precedence.md +++ b/web/docusaurus/docs/03-guides/04-textures/_model_precedence.mdx @@ -1,13 +1,13 @@ -import CodeBlock from '@theme/CodeBlock'; +import CodeBlock from "@theme/CodeBlock"; 1. `hexdoc.toml`: - { - `[textures.override.model]\n"${props.namespace}:${props.path}" = ...` - } + + {[ + "[textures.override.model]", + `${props.namespace}:${props.path}" = ...`, + ].join("\n")} + 2. Internal resources: assets/{props.namespace}/hexdoc/renders/{props.path}.\{png,gif\} - * If multiple formats exist, the one configured in `props.textures.animated.format` (default: APNG) will be used. + - If multiple formats exist, the one configured in `props.textures.animated.format` (default: APNG) will be used. 3. On-demand model rendering: assets/{props.namespace}/models/{props.path}.json 4. External resources: assets/{props.namespace}/hexdoc/renders/{props.path}.\{png,gif\} diff --git a/web/docusaurus/docs/03-guides/04-textures/index.md b/web/docusaurus/docs/03-guides/04-textures/index.md deleted file mode 100644 index 22d05782..00000000 --- a/web/docusaurus/docs/03-guides/04-textures/index.md +++ /dev/null @@ -1,36 +0,0 @@ -import Tabs from "@theme/Tabs"; -import TabItem from "@theme/TabItem"; -import ModelPrecedence from "./_model_precedence.md"; - -# Textures - -## Model precedence - -When loading or rendering a model `namespace:path` (eg. `minecraft:item/stick`), the following options will be attempted in this order; the first to successfully load will be used. - - - { - [ - { namespace: "{namespace}", path: "{path}" }, - { namespace: "minecraft", path: "item/stick" }, - ].map((props, i) => { - const { namespace, path } = props; - const key = i == 0 ? "generic" : `example${i}`; - return ( - {namespace}:{path}} - > - - - ); - }) - } - - -:::note - -In hexdoc.toml, if `textures.strict` is `True` (the default) and none of the above options are successfully loaded, the build will fail. - -::: diff --git a/web/docusaurus/docs/03-guides/04-textures/index.mdx b/web/docusaurus/docs/03-guides/04-textures/index.mdx new file mode 100644 index 00000000..6be1b7a8 --- /dev/null +++ b/web/docusaurus/docs/03-guides/04-textures/index.mdx @@ -0,0 +1,42 @@ +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; +import ModelPrecedence from "./_model_precedence.mdx"; + +# Textures + +## Model precedence + +When loading or rendering a model `namespace:path` (eg. `minecraft:item/stick`), the following options will be attempted in this order; the first to successfully load will be used. + + + {[ + { namespace: "{namespace}", path: "{path}" }, + { namespace: "minecraft", path: "item/stick" }, + ].map((props, i) => { + const { namespace, path } = props; + const key = i == 0 ? "generic" : `example${i}`; + return ( + + {namespace}:{path} + + ) + } + > + + + ); + })} + + +:::note + +In hexdoc.toml, if `textures.strict` is `True` (the default) and none of the above options are successfully loaded, the build will fail. + +::: diff --git a/web/docusaurus/docs/03-guides/05-deployment/01-github-pages.md b/web/docusaurus/docs/03-guides/05-deployment/01-github-pages.mdx similarity index 95% rename from web/docusaurus/docs/03-guides/05-deployment/01-github-pages.md rename to web/docusaurus/docs/03-guides/05-deployment/01-github-pages.mdx index f50741e4..a28935fc 100644 --- a/web/docusaurus/docs/03-guides/05-deployment/01-github-pages.md +++ b/web/docusaurus/docs/03-guides/05-deployment/01-github-pages.mdx @@ -13,9 +13,9 @@ ``` 2. In your GitHub repo, go to `Settings > Pages`. 3. In the `Build and deployment` section, set the following values: - * Source: `Deploy from a branch` - * Branch: `gh-pages` - * Folder: `/docs` + - Source: `Deploy from a branch` + - Branch: `gh-pages` + - Folder: `/docs` 4. Save your changes. :::note diff --git a/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.md b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.mdx similarity index 100% rename from web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.md rename to web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.mdx diff --git a/web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.md b/web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.md deleted file mode 100644 index fbb209d7..00000000 --- a/web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.md +++ /dev/null @@ -1,34 +0,0 @@ -# Patchouli JSON Schemas - -hexdoc automatically generates [JSON Schema](https://json-schema.org/) definitions for several Patchouli file types. - -## Types - -|Type|Schema| -|----|------| -|[Book](https://vazkiimods.github.io/Patchouli/docs/reference/book-json)|[/schema/patchouli/Book.json](pathname:///schema/patchouli/Book.json)| -|[Category](https://vazkiimods.github.io/Patchouli/docs/reference/category-json)|[/schema/patchouli/Category.json](pathname:///schema/patchouli/Category.json)| -|[Entry](https://vazkiimods.github.io/Patchouli/docs/reference/entry-json)|[/schema/patchouli/Entry.json](pathname:///schema/patchouli/Entry.json)| - -## VSCode configuration - -To use these schemas in VSCode, add the following content to your `settings.json` file: - -```json -{ - "json.schemas": [ - { - "fileMatch": ["**/patchouli_books/*/book.json"], - "url": "https://hexdoc.hexxy.media/schema/patchouli/Book.json", - }, - { - "fileMatch": ["**/patchouli_books/*/*/categories/**/*.json"], - "url": "https://hexdoc.hexxy.media/schema/patchouli/Category.json", - }, - { - "fileMatch": ["**/patchouli_books/*/*/entries/**/*.json"], - "url": "https://hexdoc.hexxy.media/schema/patchouli/Entry.json", - }, - ], -} -``` diff --git a/web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.mdx b/web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.mdx new file mode 100644 index 00000000..0b32af3f --- /dev/null +++ b/web/docusaurus/docs/03-guides/06-standalone/02-patchouli-schemas.mdx @@ -0,0 +1,34 @@ +# Patchouli JSON Schemas + +hexdoc automatically generates [JSON Schema](https://json-schema.org/) definitions for several Patchouli file types. + +## Types + +| Type | Schema | +| ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| [Book](https://vazkiimods.github.io/Patchouli/docs/reference/book-json) | [/schema/patchouli/Book.json](pathname:///schema/patchouli/Book.json) | +| [Category](https://vazkiimods.github.io/Patchouli/docs/reference/category-json) | [/schema/patchouli/Category.json](pathname:///schema/patchouli/Category.json) | +| [Entry](https://vazkiimods.github.io/Patchouli/docs/reference/entry-json) | [/schema/patchouli/Entry.json](pathname:///schema/patchouli/Entry.json) | + +## VSCode configuration + +To use these schemas in VSCode, add the following content to your `settings.json` file: + +```json +{ + "json.schemas": [ + { + "fileMatch": ["**/patchouli_books/*/book.json"], + "url": "https://hexdoc.hexxy.media/schema/patchouli/Book.json" + }, + { + "fileMatch": ["**/patchouli_books/*/*/categories/**/*.json"], + "url": "https://hexdoc.hexxy.media/schema/patchouli/Category.json" + }, + { + "fileMatch": ["**/patchouli_books/*/*/entries/**/*.json"], + "url": "https://hexdoc.hexxy.media/schema/patchouli/Entry.json" + } + ] +} +``` From 118381a1fcf7c094137b3647275b1ee23e857ac1 Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 9 May 2024 17:55:53 -0400 Subject: [PATCH 025/106] Add pre-commit hook to run Prettier --- .pre-commit-config.yaml | 6 +++ .../docs/02-getting-started/01-templates.mdx | 4 +- .../01-model-rendering/index.mdx | 54 +++++++++---------- .../src/remark/internalPathnameLinks.ts | 4 +- 4 files changed, 37 insertions(+), 31 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 92ab5fe0..42d638aa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,12 @@ repos: - id: trailing-whitespace - id: end-of-file-fixer - id: check-yaml + - repo: https://github.com/pre-commit/mirrors-prettier + rev: v3.1.0 + hooks: + - id: prettier + files: ^web/docusaurus/ + types_or: [javascript, jsx, ts, tsx, mdx] - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.3.2 hooks: diff --git a/web/docusaurus/docs/02-getting-started/01-templates.mdx b/web/docusaurus/docs/02-getting-started/01-templates.mdx index 9b67fbbd..2849e993 100644 --- a/web/docusaurus/docs/02-getting-started/01-templates.mdx +++ b/web/docusaurus/docs/02-getting-started/01-templates.mdx @@ -4,5 +4,5 @@ To simplify the setup process, hexdoc provides [Copier](https://copier.readthedo ## Templates -* [hexdoc-mod-template](https://github.com/hexdoc-dev/hexdoc-mod-template): Generic template. -* [hexdoc-hexcasting-template](https://github.com/hexdoc-dev/hexdoc-hexcasting-template): Template for Hex Casting addons. Also compatible with [HexDummy](https://github.com/FallingColors/hexdummy)! +- [hexdoc-mod-template](https://github.com/hexdoc-dev/hexdoc-mod-template): Generic template. +- [hexdoc-hexcasting-template](https://github.com/hexdoc-dev/hexdoc-hexcasting-template): Template for Hex Casting addons. Also compatible with [HexDummy](https://github.com/FallingColors/hexdummy)! diff --git a/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.mdx b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.mdx index 258b1224..d2a90f4a 100644 --- a/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.mdx +++ b/web/docusaurus/docs/03-guides/06-standalone/01-model-rendering/index.mdx @@ -7,35 +7,35 @@ For a complete example, see [examples/model_rendering](https://github.com/hexdoc ## Setup 1. In a [virtual environment](https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/#create-and-use-virtual-environments), install the following Python packages: - * `hexdoc>=1!0.1.0a15` - * `hexdoc-minecraft~={GAME_VERSION}.0` (eg. `hexdoc-minecraft~=1.19.2.0`) + - `hexdoc>=1!0.1.0a15` + - `hexdoc-minecraft~={GAME_VERSION}.0` (eg. `hexdoc-minecraft~=1.19.2.0`) 2. Create a [`hexdoc.toml` config file](../../configuration): - ```toml title="hexdoc.toml" - #:schema https://hexdoc.hexxy.media/schema/core/Properties.json - - # for standalone model rendering, just leave this as "hexdoc" - modid = "hexdoc" - - resource_dirs = [ - # path(s) to "resources" folders, resource packs, and/or mod jars where your models and textures are located - "resources", - { glob="mods/*.jar" }, - # required if your models depend on vanilla resources - { modid="minecraft" }, - { modid="hexdoc" }, - ] - - # folder where loaded resources (not rendered models) should be copied to - export_dir = "out/export" - - [textures] - strict = false - missing = [ - # add item/block/model IDs to ignore missing or broken models - "emi:*", - ] - ``` + ```toml title="hexdoc.toml" + #:schema https://hexdoc.hexxy.media/schema/core/Properties.json + + # for standalone model rendering, just leave this as "hexdoc" + modid = "hexdoc" + + resource_dirs = [ + # path(s) to "resources" folders, resource packs, and/or mod jars where your models and textures are located + "resources", + { glob="mods/*.jar" }, + # required if your models depend on vanilla resources + { modid="minecraft" }, + { modid="hexdoc" }, + ] + + # folder where loaded resources (not rendered models) should be copied to + export_dir = "out/export" + + [textures] + strict = false + missing = [ + # add item/block/model IDs to ignore missing or broken models + "emi:*", + ] + ``` ## Usage diff --git a/web/docusaurus/src/remark/internalPathnameLinks.ts b/web/docusaurus/src/remark/internalPathnameLinks.ts index 62cd7ff7..62ad6431 100644 --- a/web/docusaurus/src/remark/internalPathnameLinks.ts +++ b/web/docusaurus/src/remark/internalPathnameLinks.ts @@ -281,7 +281,7 @@ function processLinkNode(node: Link) { type: "mdxJsxAttribute", name: "rel", value: nullExpression, - } + }, ); if (node.title) { @@ -317,7 +317,7 @@ export default function plugin(): Transformer { if (!includesImportLink) { tree.children.unshift( - defaultImportNode({ name: "Link", source: "@docusaurus/Link" }) + defaultImportNode({ name: "Link", source: "@docusaurus/Link" }), ); } }; From 02f4f9ed7cadcd1a7b0630a52ef55cfcb74dac98 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 11 May 2024 22:09:03 -0400 Subject: [PATCH 026/106] Refactor minecraft module --- src/hexdoc/minecraft/model/block.py | 3 +-- src/hexdoc/minecraft/model/element.py | 13 ++++++++++--- src/hexdoc/minecraft/model/variable.py | 12 ------------ src/hexdoc/minecraft/texture/__init__.py | 0 4 files changed, 11 insertions(+), 17 deletions(-) delete mode 100644 src/hexdoc/minecraft/model/variable.py delete mode 100644 src/hexdoc/minecraft/texture/__init__.py diff --git a/src/hexdoc/minecraft/model/block.py b/src/hexdoc/minecraft/model/block.py index 392555d5..840d0a28 100644 --- a/src/hexdoc/minecraft/model/block.py +++ b/src/hexdoc/minecraft/model/block.py @@ -10,8 +10,7 @@ from hexdoc.utils.types import PydanticOrderedSet, cast_nullable from .display import DisplayPosition, DisplayPositionName -from .element import Element -from .variable import TextureVariable +from .element import Element, TextureVariable class BlockModel(HexdocModel): diff --git a/src/hexdoc/minecraft/model/element.py b/src/hexdoc/minecraft/model/element.py index e935873e..30cbb023 100644 --- a/src/hexdoc/minecraft/model/element.py +++ b/src/hexdoc/minecraft/model/element.py @@ -1,16 +1,15 @@ from __future__ import annotations import math +import re from typing import Annotated, Literal -from pydantic import Field +from pydantic import AfterValidator, Field from hexdoc.model import HexdocModel from hexdoc.model.base import IGNORE_EXTRA_CONFIG from hexdoc.utils.types import Vec3, Vec4, clamped -from .variable import TextureVariable - class Element(HexdocModel): """An element of a block/item model. Must be cubic. @@ -177,3 +176,11 @@ def get_v(self, index: Literal[0, 1, 2, 3]): def _get_shifted_index(self, index: Literal[0, 1, 2, 3]): return (index + self.rotation // 90) % 4 + + +def _validate_texture_variable(value: str): + assert re.fullmatch(r"#\w+", value) + return value + + +TextureVariable = Annotated[str, AfterValidator(_validate_texture_variable)] diff --git a/src/hexdoc/minecraft/model/variable.py b/src/hexdoc/minecraft/model/variable.py deleted file mode 100644 index 97579ce5..00000000 --- a/src/hexdoc/minecraft/model/variable.py +++ /dev/null @@ -1,12 +0,0 @@ -import re -from typing import Annotated - -from pydantic import AfterValidator - - -def _validate_texture_variable(value: str): - assert re.fullmatch(r"#\w+", value) - return value - - -TextureVariable = Annotated[str, AfterValidator(_validate_texture_variable)] diff --git a/src/hexdoc/minecraft/texture/__init__.py b/src/hexdoc/minecraft/texture/__init__.py deleted file mode 100644 index e69de29b..00000000 From dd54f03a2bbe0a638660efdf917e31a9fb46d2f8 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 11 May 2024 23:27:22 -0400 Subject: [PATCH 027/106] Refactor Properties into several files for better maintainability --- src/hexdoc/core/properties.py | 302 ----------------------- src/hexdoc/core/properties/__init__.py | 30 +++ src/hexdoc/core/properties/env.py | 55 +++++ src/hexdoc/core/properties/lang.py | 16 ++ src/hexdoc/core/properties/properties.py | 132 ++++++++++ src/hexdoc/core/properties/template.py | 61 +++++ src/hexdoc/core/properties/textures.py | 79 ++++++ 7 files changed, 373 insertions(+), 302 deletions(-) delete mode 100644 src/hexdoc/core/properties.py create mode 100644 src/hexdoc/core/properties/__init__.py create mode 100644 src/hexdoc/core/properties/env.py create mode 100644 src/hexdoc/core/properties/lang.py create mode 100644 src/hexdoc/core/properties/properties.py create mode 100644 src/hexdoc/core/properties/template.py create mode 100644 src/hexdoc/core/properties/textures.py diff --git a/src/hexdoc/core/properties.py b/src/hexdoc/core/properties.py deleted file mode 100644 index e4f299f1..00000000 --- a/src/hexdoc/core/properties.py +++ /dev/null @@ -1,302 +0,0 @@ -from __future__ import annotations - -import logging -from collections import defaultdict -from enum import StrEnum -from functools import cached_property -from pathlib import Path -from typing import Annotated, Any, Literal, Self, Sequence - -from pydantic import Field, PrivateAttr, field_validator, model_validator -from pydantic.json_schema import ( - DEFAULT_REF_TEMPLATE, - GenerateJsonSchema, - SkipJsonSchema, -) -from typing_extensions import override -from yarl import URL - -from hexdoc.model.base import HexdocSettings -from hexdoc.model.strip_hidden import StripHiddenModel -from hexdoc.utils import ( - TRACE, - PydanticOrderedSet, - RelativePath, - ValidationContext, - git_root, - load_toml_with_placeholders, - relative_path_root, -) -from hexdoc.utils.deserialize.toml import GenerateJsonSchemaTOML -from hexdoc.utils.types import PydanticURL - -from .resource import ResourceLocation -from .resource_dir import ResourceDir - -logger = logging.getLogger(__name__) - -JINJA_NAMESPACE_ALIASES = { - "patchouli": "hexdoc", -} - - -# TODO: why is this a separate class? -class BaseProperties(StripHiddenModel, ValidationContext): - env: SkipJsonSchema[EnvironmentVariableProps] - props_dir: SkipJsonSchema[Path] - - @classmethod - def load(cls, path: Path) -> Self: - return cls.load_data( - props_dir=path.parent, - data=load_toml_with_placeholders(path), - ) - - @classmethod - def load_data(cls, props_dir: Path, data: dict[str, Any]) -> Self: - props_dir = props_dir.resolve() - - with relative_path_root(props_dir): - env = EnvironmentVariableProps.model_getenv() - props = cls.model_validate( - data - | { - "env": env, - "props_dir": props_dir, - }, - ) - - logger.log(TRACE, props) - return props - - @override - @classmethod - def model_json_schema( - cls, - by_alias: bool = True, - ref_template: str = DEFAULT_REF_TEMPLATE, - schema_generator: type[GenerateJsonSchema] = GenerateJsonSchemaTOML, - mode: Literal["validation", "serialization"] = "validation", - ) -> dict[str, Any]: - return super().model_json_schema(by_alias, ref_template, schema_generator, mode) - - -class EnvironmentVariableProps(HexdocSettings): - # default Actions environment variables - github_repository: str - github_sha: str - - # set by CI - github_pages_url: PydanticURL - - # for putting books somewhere other than the site root - hexdoc_subdirectory: str | None = None - - # optional for debugging - debug_githubusercontent: PydanticURL | None = None - - @property - def asset_url(self) -> URL: - if self.debug_githubusercontent is not None: - return URL(str(self.debug_githubusercontent)) - - return ( - URL("https://raw.githubusercontent.com") - / self.repo_owner - / self.repo_name - / self.github_sha - ) - - @property - def repo_owner(self): - return self._github_repository_parts[0] - - @property - def repo_name(self): - return self._github_repository_parts[1] - - @property - def _github_repository_parts(self): - owner, repo_name = self.github_repository.split("/", maxsplit=1) - return owner, repo_name - - @model_validator(mode="after") - def _append_subdirectory(self) -> Self: - if self.hexdoc_subdirectory: - self.github_pages_url /= self.hexdoc_subdirectory - return self - - -class Properties(BaseProperties): - """Pydantic model for `hexdoc.toml` / `properties.toml`.""" - - modid: str - - book_type: str = "patchouli" - """Modid of the `hexdoc.plugin.BookPlugin` to use when loading this book.""" - - # TODO: make another properties type without book_id - book_id: ResourceLocation | None = Field(alias="book", default=None) - extra_books: list[ResourceLocation] = Field(default_factory=list) - - default_lang: str = "en_us" - default_branch: str = "main" - - is_0_black: bool = False - """If true, the style `$(0)` changes the text color to black; otherwise it resets - the text color to the default.""" - - resource_dirs: Sequence[ResourceDir] - export_dir: RelativePath | None = None - - entry_id_blacklist: set[ResourceLocation] = Field(default_factory=set) - - macros: dict[str, str] = Field(default_factory=dict) - link_overrides: dict[str, str] = Field(default_factory=dict) - - textures: TexturesProps = Field(default_factory=lambda: TexturesProps()) - - template: TemplateProps | None = None - - lang: defaultdict[ - str, - Annotated[LangProps, Field(default_factory=lambda: LangProps())], - ] = Field(default_factory=lambda: defaultdict(LangProps)) - """Per-language configuration. The key should be the language code, eg. `en_us`.""" - - extra: dict[str, Any] = Field(default_factory=dict) - - def mod_loc(self, path: str) -> ResourceLocation: - """Returns a ResourceLocation with self.modid as the namespace.""" - return ResourceLocation(self.modid, path) - - @property - def prerender_dir(self): - return self.cache_dir / "prerender" - - @property - def cache_dir(self): - return self.repo_root / ".hexdoc" - - @cached_property - def repo_root(self): - return git_root(self.props_dir) - - -class TexturesProps(StripHiddenModel): - enabled: bool = True - """Set to False to disable texture rendering.""" - strict: bool = True - """Set to False to print some errors instead of throwing them.""" - - missing: set[ResourceLocation] | Literal["*"] = Field(default_factory=set) - override: dict[ - ResourceLocation, - PNGTextureOverride | TextureTextureOverride, - ] = Field(default_factory=dict) - - large_items: bool = True - """Controls whether flat item renders should be enlarged after rendering, or left at - the default size (usually 16x16). Defaults to `True`.""" - - animated: AnimatedTexturesProps = Field( - default_factory=lambda: AnimatedTexturesProps(), - ) - - -# TODO: support item/block override -class PNGTextureOverride(StripHiddenModel): - url: PydanticURL - pixelated: bool - - -class TextureTextureOverride(StripHiddenModel): - texture: ResourceLocation - """The id of an image texture (eg. `minecraft:textures/item/stick.png`).""" - - -class AnimationFormat(StrEnum): - APNG = "apng" - GIF = "gif" - - -class AnimatedTexturesProps(StripHiddenModel): - enabled: bool = True - """If set to `False`, animated textures will be rendered as a PNG with the first - frame of the animation.""" - format: AnimationFormat = AnimationFormat.APNG - """Animated image output format. - - `apng` (the default) is higher quality, but the file size is a bit larger. - - `gif` produces smaller but lower quality files, and interpolated textures may have - issues with flickering. - """ - max_frames: Annotated[int, Field(ge=0)] = 15 * 20 # 15 seconds * 20 tps - """Maximum number of frames for animated textures (1 frame = 1 tick = 1/20 seconds). - If a texture would have more frames than this, some frames will be dropped. - - This is mostly necessary because of prismarine, which is an interpolated texture - with a total length of 6600 frames or 5.5 minutes. - - The default value is 300 frames or 15 seconds, producing about a 3 MB animation for - prismarine. - - To disable the frame limit entirely, set this value to 0. - """ - - -class TemplateProps(StripHiddenModel, validate_assignment=True): - static_dir: RelativePath | None = None - icon: RelativePath | None = None - include: PydanticOrderedSet[str] - - render_from: PydanticOrderedSet[str] = Field(None, validate_default=False) - """List of modids to include default rendered templates from. - - If not provided, defaults to `self.include`. - """ - render: dict[Path, str] = Field(default_factory=dict) - extend_render: dict[Path, str] = Field(default_factory=dict) - - redirect: tuple[Path, str] | None = (Path("index.html"), "redirect.html.jinja") - """filename, template""" - - args: dict[str, Any] - - _was_render_set: bool = PrivateAttr(False) - - @property - def override_default_render(self): - return self._was_render_set - - @field_validator("include", "render_from", mode="after") - @classmethod - def _resolve_aliases(cls, values: PydanticOrderedSet[str] | None): - if values: - for alias, replacement in JINJA_NAMESPACE_ALIASES.items(): - if alias in values: - values.remove(alias) - values.add(replacement) - return values - - @model_validator(mode="after") - def _set_default_render_from(self): - if self.render_from is None: # pyright: ignore[reportUnnecessaryComparison] - self.render_from = self.include - return self - - -class LangProps(StripHiddenModel): - """Configuration for a specific book language.""" - - quiet: bool = False - """If `True`, do not log warnings for missing translations. - - Using this option for the default language is not recommended. - """ - ignore_errors: bool = False - """If `True`, log fatal errors for this language instead of failing entirely. - - Using this option for the default language is not recommended. - """ diff --git a/src/hexdoc/core/properties/__init__.py b/src/hexdoc/core/properties/__init__.py new file mode 100644 index 00000000..e3b63cc0 --- /dev/null +++ b/src/hexdoc/core/properties/__init__.py @@ -0,0 +1,30 @@ +__all__ = [ + "JINJA_NAMESPACE_ALIASES", + "AnimatedTexturesProps", + "AnimationFormat", + "BaseProperties", + "EnvironmentVariableProps", + "LangProps", + "PNGTextureOverride", + "Properties", + "TemplateProps", + "TextureTextureOverride", + "TexturesProps", + "env", + "lang", + "properties", + "template", + "textures", +] + +from .env import EnvironmentVariableProps +from .lang import LangProps +from .properties import BaseProperties, Properties +from .template import JINJA_NAMESPACE_ALIASES, TemplateProps +from .textures import ( + AnimatedTexturesProps, + AnimationFormat, + PNGTextureOverride, + TexturesProps, + TextureTextureOverride, +) diff --git a/src/hexdoc/core/properties/env.py b/src/hexdoc/core/properties/env.py new file mode 100644 index 00000000..4fd9cc7e --- /dev/null +++ b/src/hexdoc/core/properties/env.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +from typing import Self + +from pydantic import model_validator +from yarl import URL + +from hexdoc.model.base import HexdocSettings +from hexdoc.utils.types import PydanticURL + + +class EnvironmentVariableProps(HexdocSettings): + # default Actions environment variables + github_repository: str + github_sha: str + + # set by CI + github_pages_url: PydanticURL + + # for putting books somewhere other than the site root + hexdoc_subdirectory: str | None = None + + # optional for debugging + debug_githubusercontent: PydanticURL | None = None + + @property + def asset_url(self) -> URL: + if self.debug_githubusercontent is not None: + return URL(str(self.debug_githubusercontent)) + + return ( + URL("https://raw.githubusercontent.com") + / self.repo_owner + / self.repo_name + / self.github_sha + ) + + @property + def repo_owner(self): + return self._github_repository_parts[0] + + @property + def repo_name(self): + return self._github_repository_parts[1] + + @property + def _github_repository_parts(self): + owner, repo_name = self.github_repository.split("/", maxsplit=1) + return owner, repo_name + + @model_validator(mode="after") + def _append_subdirectory(self) -> Self: + if self.hexdoc_subdirectory: + self.github_pages_url /= self.hexdoc_subdirectory + return self diff --git a/src/hexdoc/core/properties/lang.py b/src/hexdoc/core/properties/lang.py new file mode 100644 index 00000000..f4b0dc2f --- /dev/null +++ b/src/hexdoc/core/properties/lang.py @@ -0,0 +1,16 @@ +from hexdoc.model.strip_hidden import StripHiddenModel + + +class LangProps(StripHiddenModel): + """Configuration for a specific book language.""" + + quiet: bool = False + """If `True`, do not log warnings for missing translations. + + Using this option for the default language is not recommended. + """ + ignore_errors: bool = False + """If `True`, log fatal errors for this language instead of failing entirely. + + Using this option for the default language is not recommended. + """ diff --git a/src/hexdoc/core/properties/properties.py b/src/hexdoc/core/properties/properties.py new file mode 100644 index 00000000..f021c3a2 --- /dev/null +++ b/src/hexdoc/core/properties/properties.py @@ -0,0 +1,132 @@ +from __future__ import annotations + +import logging +from collections import defaultdict +from functools import cached_property +from pathlib import Path +from typing import Annotated, Any, Literal, Self, Sequence + +from pydantic import Field +from pydantic.json_schema import ( + DEFAULT_REF_TEMPLATE, + GenerateJsonSchema, + SkipJsonSchema, +) +from typing_extensions import override + +from hexdoc.model.strip_hidden import StripHiddenModel +from hexdoc.utils import ( + TRACE, + RelativePath, + ValidationContext, + git_root, + load_toml_with_placeholders, + relative_path_root, +) +from hexdoc.utils.deserialize.toml import GenerateJsonSchemaTOML + +from ..resource import ResourceLocation +from ..resource_dir import ResourceDir +from .env import EnvironmentVariableProps +from .lang import LangProps +from .template import TemplateProps +from .textures import TexturesProps + +logger = logging.getLogger(__name__) + + +# TODO: why is this a separate class? +class BaseProperties(StripHiddenModel, ValidationContext): + env: SkipJsonSchema[EnvironmentVariableProps] + props_dir: SkipJsonSchema[Path] + + @classmethod + def load(cls, path: Path) -> Self: + return cls.load_data( + props_dir=path.parent, + data=load_toml_with_placeholders(path), + ) + + @classmethod + def load_data(cls, props_dir: Path, data: dict[str, Any]) -> Self: + props_dir = props_dir.resolve() + + with relative_path_root(props_dir): + env = EnvironmentVariableProps.model_getenv() + props = cls.model_validate( + data + | { + "env": env, + "props_dir": props_dir, + }, + ) + + logger.log(TRACE, props) + return props + + @override + @classmethod + def model_json_schema( + cls, + by_alias: bool = True, + ref_template: str = DEFAULT_REF_TEMPLATE, + schema_generator: type[GenerateJsonSchema] = GenerateJsonSchemaTOML, + mode: Literal["validation", "serialization"] = "validation", + ) -> dict[str, Any]: + return super().model_json_schema(by_alias, ref_template, schema_generator, mode) + + +class Properties(BaseProperties): + """Pydantic model for `hexdoc.toml` / `properties.toml`.""" + + modid: str + + book_type: str = "patchouli" + """Modid of the `hexdoc.plugin.BookPlugin` to use when loading this book.""" + + # TODO: make another properties type without book_id + book_id: ResourceLocation | None = Field(alias="book", default=None) + extra_books: list[ResourceLocation] = Field(default_factory=list) + + default_lang: str = "en_us" + default_branch: str = "main" + + is_0_black: bool = False + """If true, the style `$(0)` changes the text color to black; otherwise it resets + the text color to the default.""" + + resource_dirs: Sequence[ResourceDir] + export_dir: RelativePath | None = None + + entry_id_blacklist: set[ResourceLocation] = Field(default_factory=set) + + macros: dict[str, str] = Field(default_factory=dict) + link_overrides: dict[str, str] = Field(default_factory=dict) + + textures: TexturesProps = Field(default_factory=lambda: TexturesProps()) + + template: TemplateProps | None = None + + lang: defaultdict[ + str, + Annotated[LangProps, Field(default_factory=lambda: LangProps())], + ] = Field(default_factory=lambda: defaultdict(LangProps)) + """Per-language configuration. The key should be the language code, eg. `en_us`.""" + + extra: dict[str, Any] = Field(default_factory=dict) + + def mod_loc(self, path: str) -> ResourceLocation: + """Returns a ResourceLocation with self.modid as the namespace.""" + return ResourceLocation(self.modid, path) + + @property + def prerender_dir(self): + return self.cache_dir / "prerender" + + @property + def cache_dir(self): + return self.repo_root / ".hexdoc" + + @cached_property + def repo_root(self): + return git_root(self.props_dir) diff --git a/src/hexdoc/core/properties/template.py b/src/hexdoc/core/properties/template.py new file mode 100644 index 00000000..0bb4ad12 --- /dev/null +++ b/src/hexdoc/core/properties/template.py @@ -0,0 +1,61 @@ +from __future__ import annotations + +import logging +from pathlib import Path +from typing import Any + +from pydantic import Field, PrivateAttr, field_validator, model_validator + +from hexdoc.model.strip_hidden import StripHiddenModel +from hexdoc.utils import ( + PydanticOrderedSet, + RelativePath, +) + +logger = logging.getLogger(__name__) + + +JINJA_NAMESPACE_ALIASES = { + "patchouli": "hexdoc", +} + + +class TemplateProps(StripHiddenModel, validate_assignment=True): + static_dir: RelativePath | None = None + icon: RelativePath | None = None + include: PydanticOrderedSet[str] + + render_from: PydanticOrderedSet[str] = Field(None, validate_default=False) + """List of modids to include default rendered templates from. + + If not provided, defaults to `self.include`. + """ + render: dict[Path, str] = Field(default_factory=dict) + extend_render: dict[Path, str] = Field(default_factory=dict) + + redirect: tuple[Path, str] | None = (Path("index.html"), "redirect.html.jinja") + """filename, template""" + + args: dict[str, Any] + + _was_render_set: bool = PrivateAttr(False) + + @property + def override_default_render(self): + return self._was_render_set + + @field_validator("include", "render_from", mode="after") + @classmethod + def _resolve_aliases(cls, values: PydanticOrderedSet[str] | None): + if values: + for alias, replacement in JINJA_NAMESPACE_ALIASES.items(): + if alias in values: + values.remove(alias) + values.add(replacement) + return values + + @model_validator(mode="after") + def _set_default_render_from(self): + if self.render_from is None: # pyright: ignore[reportUnnecessaryComparison] + self.render_from = self.include + return self diff --git a/src/hexdoc/core/properties/textures.py b/src/hexdoc/core/properties/textures.py new file mode 100644 index 00000000..72bd2062 --- /dev/null +++ b/src/hexdoc/core/properties/textures.py @@ -0,0 +1,79 @@ +from __future__ import annotations + +import logging +from enum import StrEnum +from typing import Annotated, Literal + +from pydantic import Field + +from hexdoc.model.strip_hidden import StripHiddenModel +from hexdoc.utils.types import PydanticURL + +from ..resource import ResourceLocation + +logger = logging.getLogger(__name__) + + +# TODO: support item/block override +class PNGTextureOverride(StripHiddenModel): + url: PydanticURL + pixelated: bool + + +class TextureTextureOverride(StripHiddenModel): + texture: ResourceLocation + """The id of an image texture (eg. `minecraft:textures/item/stick.png`).""" + + +class AnimationFormat(StrEnum): + APNG = "apng" + GIF = "gif" + + +class AnimatedTexturesProps(StripHiddenModel): + enabled: bool = True + """If set to `False`, animated textures will be rendered as a PNG with the first + frame of the animation.""" + format: AnimationFormat = AnimationFormat.APNG + """Animated image output format. + + `apng` (the default) is higher quality, but the file size is a bit larger. + + `gif` produces smaller but lower quality files, and interpolated textures may have + issues with flickering. + """ + max_frames: Annotated[int, Field(ge=0)] = 15 * 20 # 15 seconds * 20 tps + """Maximum number of frames for animated textures (1 frame = 1 tick = 1/20 seconds). + If a texture would have more frames than this, some frames will be dropped. + + This is mostly necessary because of prismarine, which is an interpolated texture + with a total length of 6600 frames or 5.5 minutes. + + The default value is 300 frames or 15 seconds, producing about a 3 MB animation for + prismarine. + + To disable the frame limit entirely, set this value to 0. + """ + + +class OverridesProps(StripHiddenModel): + pass + + +class TexturesProps(StripHiddenModel): + enabled: bool = True + """Set to False to disable model rendering.""" + strict: bool = True + """Set to False to print some errors instead of throwing them.""" + large_items: bool = True + """Controls whether flat item renders should be enlarged after rendering, or left at + the default size (usually 16x16). Defaults to `True`.""" + + missing: set[ResourceLocation] | Literal["*"] = Field(default_factory=set) + + animated: AnimatedTexturesProps = Field(default_factory=AnimatedTexturesProps) + + override: dict[ + ResourceLocation, + PNGTextureOverride | TextureTextureOverride, + ] = Field(default_factory=dict) From 662a25cf9ed1bd565dde40b7eb8f5d6dc27e5b5b Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 01:16:04 -0400 Subject: [PATCH 028/106] Implement new model loading class --- src/hexdoc/core/properties/__init__.py | 2 + src/hexdoc/core/properties/textures.py | 29 +++- src/hexdoc/graphics/renderer.py | 8 +- src/hexdoc/minecraft/model_loader.py | 149 ++++++++++++++++++ .../04-textures/_model_precedence.mdx | 2 +- 5 files changed, 181 insertions(+), 9 deletions(-) create mode 100644 src/hexdoc/minecraft/model_loader.py diff --git a/src/hexdoc/core/properties/__init__.py b/src/hexdoc/core/properties/__init__.py index e3b63cc0..be9bcd98 100644 --- a/src/hexdoc/core/properties/__init__.py +++ b/src/hexdoc/core/properties/__init__.py @@ -8,6 +8,7 @@ "PNGTextureOverride", "Properties", "TemplateProps", + "TextureOverrides", "TextureTextureOverride", "TexturesProps", "env", @@ -25,6 +26,7 @@ AnimatedTexturesProps, AnimationFormat, PNGTextureOverride, + TextureOverrides, TexturesProps, TextureTextureOverride, ) diff --git a/src/hexdoc/core/properties/textures.py b/src/hexdoc/core/properties/textures.py index 72bd2062..5658ab97 100644 --- a/src/hexdoc/core/properties/textures.py +++ b/src/hexdoc/core/properties/textures.py @@ -5,6 +5,7 @@ from typing import Annotated, Literal from pydantic import Field +from typing_extensions import deprecated from hexdoc.model.strip_hidden import StripHiddenModel from hexdoc.utils.types import PydanticURL @@ -29,6 +30,14 @@ class AnimationFormat(StrEnum): APNG = "apng" GIF = "gif" + @property + def suffix(self): + match self: + case AnimationFormat.APNG: + return ".png" + case AnimationFormat.GIF: + return ".gif" + class AnimatedTexturesProps(StripHiddenModel): enabled: bool = True @@ -56,8 +65,16 @@ class AnimatedTexturesProps(StripHiddenModel): """ -class OverridesProps(StripHiddenModel): - pass +class TextureOverrides(StripHiddenModel): + models: dict[ResourceLocation, ResourceLocation | PydanticURL] = Field( + default_factory=dict + ) + """Model overrides. + + Key: model id (eg. `minecraft:item/stick`). + + Value: texture id (eg. `minecraft:textures/item/stick.png`) or image URL. + """ class TexturesProps(StripHiddenModel): @@ -73,7 +90,13 @@ class TexturesProps(StripHiddenModel): animated: AnimatedTexturesProps = Field(default_factory=AnimatedTexturesProps) + overrides: TextureOverrides = Field(default_factory=TextureOverrides) + override: dict[ ResourceLocation, PNGTextureOverride | TextureTextureOverride, - ] = Field(default_factory=dict) + ] = Field( + default_factory=dict, + deprecated=deprecated("Use textures.overrides.model instead"), + ) + """DEPRECATED.""" diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index 54214408..48a2f0bf 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -135,27 +135,25 @@ def _load_layers(self, model: BlockModel): def _save_animation(self, output_path: Path, frames: list[Image.Image]): kwargs: dict[str, Any] - match self.texture_props.animated.format: + match output_format := self.texture_props.animated.format: case AnimationFormat.APNG: - suffix = ".png" kwargs = dict( disposal=APNGDisposal.OP_BACKGROUND, ) case AnimationFormat.GIF: - suffix = ".gif" kwargs = dict( loop=0, # loop forever disposal=2, # restore to background color ) frames[0].save( - output_path.with_suffix(suffix), + output_path.with_suffix(output_format.suffix), save_all=True, append_images=frames[1:], duration=1000 / 20, **kwargs, ) - return suffix + return output_format.suffix def destroy(self): self.window.destroy() diff --git a/src/hexdoc/minecraft/model_loader.py b/src/hexdoc/minecraft/model_loader.py new file mode 100644 index 00000000..4f8934d9 --- /dev/null +++ b/src/hexdoc/minecraft/model_loader.py @@ -0,0 +1,149 @@ +import logging +import shutil +from abc import ABC, abstractmethod +from dataclasses import dataclass, field +from pathlib import Path + +from typing_extensions import override +from yarl import URL + +from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.graphics import ModelRenderer + +from .model import BlockModel + +logger = logging.getLogger(__name__) + + +@dataclass(kw_only=True) +class ModelLoader: + loader: ModResourceLoader + renderer: ModelRenderer + site_dir: Path + site_url: URL + + def __post_init__(self): + self._cache = dict[ResourceLocation, URL]() + + self._strategies: list[ModelLoaderStrategy] = [ + FromProps(self), + FromResources(self, internal=True), + FromRenderer(self), + FromResources(self, internal=False), + ] + + @property + def props(self): + return self.loader.props + + def render_block(self, block_id: ResourceLocation): + return self.render_model("block" / block_id) + + def render_item(self, item_id: ResourceLocation): + return self.render_model("item" / item_id) + + def render_model(self, model_id: ResourceLocation): + if result := self._cache.get(model_id): + logger.debug(f"Cache hit: {model_id} = {result}") + return result + + _, model = BlockModel.load_and_resolve(self.loader, model_id) + for override_id, override_model in self._get_overrides(model_id, model): + for strategy in self._strategies: + try: + if result := strategy(override_id, override_model): + self._cache[model_id] = self._cache[override_id] = result + return result + except Exception: + logger.debug( + f"Exception while rendering override: {override_id}", + exc_info=True, + ) + + message = f"All strategies failed to render model: {model_id}" + if self.props.textures.strict: + raise ValueError(message) + logger.error(message) + + def _get_overrides(self, model_id: ResourceLocation, model: BlockModel): + # TODO: implement + yield model_id, model + + +@dataclass +class ModelLoaderStrategy(ABC): + ml: ModelLoader = field(repr=False) + + model_id: ResourceLocation = field(init=False, repr=False) + model: BlockModel = field(init=False, repr=False) + + def __call__(self, model_id: ResourceLocation, model: BlockModel) -> URL | None: + logger.debug(f"Attempting strategy: {self}") + self.model_id = model_id + self.model = model + return self._execute() + + @abstractmethod + def _execute(self) -> URL | None: ... + + def _from_existing_image(self, src: Path): + fragment = self._get_fragment(src.suffix) + shutil.copyfile(src, self.ml.site_dir / fragment) + return self._fragment_to_url(fragment) + + def _get_fragment(self, suffix: str = ".png"): + path = Path("renders") / self.model_id.namespace / self.model_id.path + return path.with_suffix(suffix) + + def _fragment_to_url(self, fragment: Path): + return self.ml.site_url.joinpath(*fragment.parts) + + +class FromProps(ModelLoaderStrategy): + @override + def _execute(self) -> URL | None: + match self.ml.props.textures.overrides.models.get(self.model_id): + case ResourceLocation() as texture_id: + _, src = self.ml.loader.find_resource("assets", "", texture_id) + return self._from_existing_image(src) + case URL() as url: + return url + case None: + logger.debug(f"No props override for model: {self.model_id}") + return None + + +@dataclass +class FromResources(ModelLoaderStrategy): + internal: bool + + @override + def _execute(self) -> URL | None: + preferred_suffix = self.ml.props.textures.animated.format.suffix + + src = None + for resource_dir, _, path in self.ml.loader.find_resources( + "assets", + namespace=self.model_id.namespace, + folder="hexdoc/renders", + glob=self.model_id.path + ".{png,gif}", + allow_missing=True, + ): + if resource_dir.internal == self.internal: + src = path + if path.suffix == preferred_suffix: + break + + if src: + return self._from_existing_image(src) + + type_ = "internal" if self.internal else "external" + logger.debug(f"No {type_} rendered resource for model: {self.model_id}") + + +class FromRenderer(ModelLoaderStrategy): + @override + def _execute(self) -> URL | None: + fragment = self._get_fragment() + suffix = self.ml.renderer.render_model(self.model, self.ml.site_dir / fragment) + return self._fragment_to_url(fragment.with_suffix(suffix)) diff --git a/web/docusaurus/docs/03-guides/04-textures/_model_precedence.mdx b/web/docusaurus/docs/03-guides/04-textures/_model_precedence.mdx index 9f01b7f8..03e8301c 100644 --- a/web/docusaurus/docs/03-guides/04-textures/_model_precedence.mdx +++ b/web/docusaurus/docs/03-guides/04-textures/_model_precedence.mdx @@ -3,7 +3,7 @@ import CodeBlock from "@theme/CodeBlock"; 1. `hexdoc.toml`: {[ - "[textures.override.model]", + "[textures.overrides.models]", `${props.namespace}:${props.path}" = ...`, ].join("\n")} From 659bb1ba5d157137f8d1571bb414c4bddecf4aa3 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 11:47:56 -0400 Subject: [PATCH 029/106] Simplify ModelLoader implementation, add render_texture method --- src/hexdoc/graphics/__init__.py | 2 + src/hexdoc/graphics/renderer.py | 4 + src/hexdoc/graphics/texture.py | 21 ++- src/hexdoc/minecraft/model/block.py | 9 +- src/hexdoc/minecraft/model_loader.py | 205 ++++++++++++++++----------- 5 files changed, 151 insertions(+), 90 deletions(-) diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index 528fe49b..cb4e8968 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -1,7 +1,9 @@ __all__ = [ "DebugType", "ModelRenderer", + "ModelTexture", ] from .renderer import ModelRenderer +from .texture import ModelTexture from .utils import DebugType diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index 48a2f0bf..abfd8e50 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -70,9 +70,13 @@ def render_model( else: frames = self._render_block(model) + return self.save_image(output_path, frames) + + def save_image(self, output_path: str | Path, frames: list[Image.Image]): output_path = Path(output_path) if self.output_dir and not output_path.is_absolute(): output_path = self.output_dir / output_path + output_path.parent.mkdir(parents=True, exist_ok=True) match frames: diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index 9e29125f..be49152f 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -18,24 +18,35 @@ logger = logging.getLogger(__name__) -_TEXTURE_CACHE: dict[ResourceLocation, ModelTexture] = {} +# TODO: maybe put this in some system in ModResourceLoader? (see weakref.finalize) +# then we could clear the cache and free up memory when the loader is closed +_TEXTURE_CACHE: dict[ResourceLocation | Path, ModelTexture] = {} @dataclass(kw_only=True) class ModelTexture: - texture_id: ResourceLocation + texture_id: ResourceLocation | Path image: Image.Image animation: Animation | None layer_index: int = -1 props: AnimatedTexturesProps @classmethod - def load(cls, loader: ModResourceLoader, texture_id: ResourceLocation): + def load(cls, loader: ModResourceLoader, texture_id: ResourceLocation | Path): if cached := _TEXTURE_CACHE.get(texture_id): + logger.debug(f"Cache hit: {texture_id}") return cached - logger.debug(f"Loading texture: {texture_id}") - _, path = loader.find_resource("assets", "textures", texture_id + ".png") + match texture_id: + case ResourceLocation(): + _, path = loader.find_resource( + "assets", + "textures", + texture_id + ".png", + ) + logger.debug(f"Loading texture {texture_id}: {path}") + case Path() as path: + logger.debug(f"Loading texture: {texture_id}") texture = cls( texture_id=texture_id, diff --git a/src/hexdoc/minecraft/model/block.py b/src/hexdoc/minecraft/model/block.py index 840d0a28..55e62e5a 100644 --- a/src/hexdoc/minecraft/model/block.py +++ b/src/hexdoc/minecraft/model/block.py @@ -79,6 +79,7 @@ class BlockModel(HexdocModel): # internal fields _is_generated_item: bool = PrivateAttr(False) + _id: ResourceLocation = PrivateAttr(None) @classmethod def load_and_resolve(cls, loader: ModResourceLoader, model_id: ResourceLocation): @@ -89,12 +90,14 @@ def load_and_resolve(cls, loader: ModResourceLoader, model_id: ResourceLocation) def load_only(cls, loader: ModResourceLoader, model_id: ResourceLocation): """Loads the given model without resolving it.""" try: - return loader.load_resource( + resource_dir, model = loader.load_resource( type="assets", folder="models", id=model_id, decode=cls.model_validate_json, ) + model._id = model_id + return resource_dir, model except Exception as e: e.add_note(f" note: {model_id=}") raise @@ -151,6 +154,10 @@ def is_resolved(self): def is_generated_item(self): return self._is_generated_item + @property + def id(self): + return self._id + @cached_property def resolved_textures(self): assert self.is_resolved, "Cannot resolve textures for unresolved model" diff --git a/src/hexdoc/minecraft/model_loader.py b/src/hexdoc/minecraft/model_loader.py index 4f8934d9..046cacc3 100644 --- a/src/hexdoc/minecraft/model_loader.py +++ b/src/hexdoc/minecraft/model_loader.py @@ -1,35 +1,41 @@ import logging -import shutil -from abc import ABC, abstractmethod -from dataclasses import dataclass, field +from dataclasses import dataclass from pathlib import Path +from typing import Callable -from typing_extensions import override from yarl import URL from hexdoc.core import ModResourceLoader, ResourceLocation -from hexdoc.graphics import ModelRenderer +from hexdoc.graphics import ModelRenderer, ModelTexture +from hexdoc.utils import ValidationContext from .model import BlockModel logger = logging.getLogger(__name__) +MISSING_TEXTURE_ID = ResourceLocation("hexdoc", "textures/item/missing.png") + +ModelLoaderStrategy = Callable[[BlockModel], URL | None] + @dataclass(kw_only=True) -class ModelLoader: +class ModelLoader(ValidationContext): loader: ModResourceLoader renderer: ModelRenderer site_dir: Path - site_url: URL + site_url: URL # this should probably be a relative path def __post_init__(self): - self._cache = dict[ResourceLocation, URL]() + # TODO: see cache comment in hexdoc.graphics.texture + # (though it's less of an issue here since these aren't globals) + self._model_cache = dict[ResourceLocation, URL]() + self._texture_cache = dict[ResourceLocation, URL]() self._strategies: list[ModelLoaderStrategy] = [ - FromProps(self), - FromResources(self, internal=True), - FromRenderer(self), - FromResources(self, internal=False), + self._from_props, + self._from_resources(internal=True), + self._from_renderer, + self._from_resources(internal=False), ] @property @@ -43,107 +49,138 @@ def render_item(self, item_id: ResourceLocation): return self.render_model("item" / item_id) def render_model(self, model_id: ResourceLocation): - if result := self._cache.get(model_id): - logger.debug(f"Cache hit: {model_id} = {result}") - return result + model = self._load_model(model_id) + if isinstance(model, URL): + return model - _, model = BlockModel.load_and_resolve(self.loader, model_id) - for override_id, override_model in self._get_overrides(model_id, model): + for override_model in self._get_overrides(model): + if isinstance(override_model, URL): + return override_model for strategy in self._strategies: + logger.debug(f"Attempting model strategy: {strategy.__name__}") try: - if result := strategy(override_id, override_model): - self._cache[model_id] = self._cache[override_id] = result + if result := strategy(override_model): + self._model_cache[model_id] = result + self._model_cache[override_model.id] = result return result except Exception: + # TODO: probably shouldn't just swallow all errors like this. logger.debug( - f"Exception while rendering override: {override_id}", + f"Exception while rendering override: {override_model.id}", exc_info=True, ) - message = f"All strategies failed to render model: {model_id}" + self._fail(f"All strategies failed to render model: {model_id}") + + def render_texture(self, texture_id: ResourceLocation) -> URL | None: + if result := self._texture_cache.get(texture_id): + return result + + try: + _, path = self.loader.find_resource("assets", "", texture_id) + result = self._render_existing_texture(path, texture_id) + self._texture_cache[texture_id] = result + return result + except FileNotFoundError: + # prevent infinite recursion if something really weird happens + # use RuntimeError instead of assert so Pydantic doesn't catch it + if texture_id == MISSING_TEXTURE_ID: + raise RuntimeError( + f"Built-in missing texture {MISSING_TEXTURE_ID} not found" + + " (this should never happen)" + ) + + self._fail(f"Failed to find texture: {texture_id}") + + def _fail(self, message: str): if self.props.textures.strict: raise ValueError(message) logger.error(message) + return self.render_texture(MISSING_TEXTURE_ID) - def _get_overrides(self, model_id: ResourceLocation, model: BlockModel): - # TODO: implement - yield model_id, model - - -@dataclass -class ModelLoaderStrategy(ABC): - ml: ModelLoader = field(repr=False) - - model_id: ResourceLocation = field(init=False, repr=False) - model: BlockModel = field(init=False, repr=False) + def _get_overrides(self, model: BlockModel): + # TODO: implement (with _load_model) + yield model - def __call__(self, model_id: ResourceLocation, model: BlockModel) -> URL | None: - logger.debug(f"Attempting strategy: {self}") - self.model_id = model_id - self.model = model - return self._execute() + def _load_model(self, model_id: ResourceLocation): + if result := self._model_cache.get(model_id): + logger.debug(f"Cache hit: {model_id} = {result}") + return result - @abstractmethod - def _execute(self) -> URL | None: ... + _, model = BlockModel.load_and_resolve(self.loader, model_id) + return model - def _from_existing_image(self, src: Path): - fragment = self._get_fragment(src.suffix) - shutil.copyfile(src, self.ml.site_dir / fragment) - return self._fragment_to_url(fragment) + def _render_existing_texture(self, src: Path, output_id: ResourceLocation): + fragment = self._get_fragment(output_id, src.suffix) + texture = ModelTexture.load(self.loader, src) + suffix = self.renderer.save_image(self.site_dir / fragment, texture.frames) + return self._fragment_to_url(fragment.with_suffix(suffix)) - def _get_fragment(self, suffix: str = ".png"): - path = Path("renders") / self.model_id.namespace / self.model_id.path + def _get_fragment(self, output_id: ResourceLocation, suffix: str = ".png"): + path = Path("renders") / output_id.namespace / output_id.path return path.with_suffix(suffix) def _fragment_to_url(self, fragment: Path): - return self.ml.site_url.joinpath(*fragment.parts) + return self.site_url.joinpath(*fragment.parts) + + def _find_texture( + self, + texture_id: ResourceLocation, + *, + folder: str, + internal: bool, + ): + preferred_suffix = self.props.textures.animated.format.suffix + + path = None + prev_dir = None + for resource_dir, _, path in self.loader.find_resources( + "assets", + namespace=texture_id.namespace, + folder=folder, + glob=texture_id.path + ".{png,gif}", + allow_missing=True, + ): + # after we find a match, only keep looking in the same resource dir + # so we don't break the load order + if prev_dir and prev_dir != resource_dir: + break + if resource_dir.internal == internal: + path = path + prev_dir = resource_dir + if path.suffix == preferred_suffix: + break + return path + # model rendering strategies -class FromProps(ModelLoaderStrategy): - @override - def _execute(self) -> URL | None: - match self.ml.props.textures.overrides.models.get(self.model_id): + def _from_props(self, model: BlockModel): + match self.props.textures.overrides.models.get(model.id): case ResourceLocation() as texture_id: - _, src = self.ml.loader.find_resource("assets", "", texture_id) - return self._from_existing_image(src) + _, src = self.loader.find_resource("assets", "", texture_id) + return self._render_existing_texture(src, model.id) case URL() as url: return url case None: - logger.debug(f"No props override for model: {self.model_id}") + logger.debug(f"No props override for model: {model.id}") return None + def _from_resources(self, *, internal: bool): + type_ = "internal" if internal else "external" -@dataclass -class FromResources(ModelLoaderStrategy): - internal: bool - - @override - def _execute(self) -> URL | None: - preferred_suffix = self.ml.props.textures.animated.format.suffix - - src = None - for resource_dir, _, path in self.ml.loader.find_resources( - "assets", - namespace=self.model_id.namespace, - folder="hexdoc/renders", - glob=self.model_id.path + ".{png,gif}", - allow_missing=True, - ): - if resource_dir.internal == self.internal: - src = path - if path.suffix == preferred_suffix: - break - - if src: - return self._from_existing_image(src) - - type_ = "internal" if self.internal else "external" - logger.debug(f"No {type_} rendered resource for model: {self.model_id}") + def inner(model: BlockModel): + if path := self._find_texture( + model.id, + folder="hexdoc/renders", + internal=internal, + ): + return self._render_existing_texture(path, model.id) + logger.debug(f"No {type_} rendered resource for model: {model.id}") + inner.__name__ = f"_from_resources({internal=})" + return inner -class FromRenderer(ModelLoaderStrategy): - @override - def _execute(self) -> URL | None: - fragment = self._get_fragment() - suffix = self.ml.renderer.render_model(self.model, self.ml.site_dir / fragment) + def _from_renderer(self, model: BlockModel): + fragment = self._get_fragment(model.id) + suffix = self.renderer.render_model(model, self.site_dir / fragment) return self._fragment_to_url(fragment.with_suffix(suffix)) From 3a03310efd37a514db390b8e475302eb5f6411a6 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 11:52:45 -0400 Subject: [PATCH 030/106] Only run pyright hook on push to reduce friction --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 42d638aa..6ed17953 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,6 +25,7 @@ repos: hooks: - id: pyright name: pyright + stages: [pre-push] entry: nox -s pyright -- language: python language_version: '3.11' From 183246a7648bb051eca978bad4b54ae4cb01e473 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 11:55:36 -0400 Subject: [PATCH 031/106] Fix pre-push hook not running --- .pre-commit-config.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6ed17953..bb041ee0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,7 @@ exclude: '__snapshots__|^vendor/' - +default_install_hook_types: + - pre-commit + - pre-push repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.5.0 From f99d6d0514b8ef01b251e4395f6c62c5521d8bfb Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 11:57:07 -0400 Subject: [PATCH 032/106] Don't run commit hooks on push --- .pre-commit-config.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bb041ee0..1a64fa22 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,6 @@ exclude: '__snapshots__|^vendor/' +default_stages: + - pre-commit default_install_hook_types: - pre-commit - pre-push From fd84f04db52234246de977114d23a4f854ea5aa8 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 11:58:42 -0400 Subject: [PATCH 033/106] Revert "Don't run commit hooks on push" This reverts commit f99d6d0514b8ef01b251e4395f6c62c5521d8bfb. --- .pre-commit-config.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1a64fa22..bb041ee0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,4 @@ exclude: '__snapshots__|^vendor/' -default_stages: - - pre-commit default_install_hook_types: - pre-commit - pre-push From 1c0a94a0e99a9ebb32bd761773e9486d8768999f Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 12:44:15 -0400 Subject: [PATCH 034/106] Move ModelLoader from minecraft to graphics --- src/hexdoc/graphics/__init__.py | 2 ++ src/hexdoc/{minecraft/model_loader.py => graphics/loader.py} | 5 +++-- src/hexdoc/minecraft/model/blockstate.py | 3 +-- src/hexdoc/minecraft/model/element.py | 3 +-- 4 files changed, 7 insertions(+), 6 deletions(-) rename src/hexdoc/{minecraft/model_loader.py => graphics/loader.py} (98%) diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index cb4e8968..24f12232 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -1,9 +1,11 @@ __all__ = [ "DebugType", + "ModelLoader", "ModelRenderer", "ModelTexture", ] +from .loader import ModelLoader from .renderer import ModelRenderer from .texture import ModelTexture from .utils import DebugType diff --git a/src/hexdoc/minecraft/model_loader.py b/src/hexdoc/graphics/loader.py similarity index 98% rename from src/hexdoc/minecraft/model_loader.py rename to src/hexdoc/graphics/loader.py index 046cacc3..aa96c59b 100644 --- a/src/hexdoc/minecraft/model_loader.py +++ b/src/hexdoc/graphics/loader.py @@ -6,10 +6,11 @@ from yarl import URL from hexdoc.core import ModResourceLoader, ResourceLocation -from hexdoc.graphics import ModelRenderer, ModelTexture +from hexdoc.minecraft.model import BlockModel from hexdoc.utils import ValidationContext -from .model import BlockModel +from .renderer import ModelRenderer +from .texture import ModelTexture logger = logging.getLogger(__name__) diff --git a/src/hexdoc/minecraft/model/blockstate.py b/src/hexdoc/minecraft/model/blockstate.py index a8012589..6ad337e8 100644 --- a/src/hexdoc/minecraft/model/blockstate.py +++ b/src/hexdoc/minecraft/model/blockstate.py @@ -6,8 +6,7 @@ from pydantic import AfterValidator, BeforeValidator, ConfigDict, model_validator from hexdoc.core import ResourceLocation -from hexdoc.model import HexdocModel -from hexdoc.model.base import DEFAULT_CONFIG +from hexdoc.model import DEFAULT_CONFIG, HexdocModel class Blockstate(HexdocModel): diff --git a/src/hexdoc/minecraft/model/element.py b/src/hexdoc/minecraft/model/element.py index 30cbb023..01ac7e27 100644 --- a/src/hexdoc/minecraft/model/element.py +++ b/src/hexdoc/minecraft/model/element.py @@ -6,8 +6,7 @@ from pydantic import AfterValidator, Field -from hexdoc.model import HexdocModel -from hexdoc.model.base import IGNORE_EXTRA_CONFIG +from hexdoc.model import IGNORE_EXTRA_CONFIG, HexdocModel from hexdoc.utils.types import Vec3, Vec4, clamped From e024a5efad166503e2f7b36f7c88d517f4f76b14 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sun, 12 May 2024 12:46:15 -0400 Subject: [PATCH 035/106] Actually use return value of ModelLoader._fail --- src/hexdoc/graphics/loader.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index aa96c59b..a29c7857 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -71,7 +71,7 @@ def render_model(self, model_id: ResourceLocation): exc_info=True, ) - self._fail(f"All strategies failed to render model: {model_id}") + return self._fail(f"All strategies failed to render model: {model_id}") def render_texture(self, texture_id: ResourceLocation) -> URL | None: if result := self._texture_cache.get(texture_id): @@ -91,7 +91,7 @@ def render_texture(self, texture_id: ResourceLocation) -> URL | None: + " (this should never happen)" ) - self._fail(f"Failed to find texture: {texture_id}") + return self._fail(f"Failed to find texture: {texture_id}") def _fail(self, message: str): if self.props.textures.strict: From 9739050e2c64b795fa0e6f4f3a2e9553a3727c93 Mon Sep 17 00:00:00 2001 From: object-Object Date: Tue, 14 May 2024 01:12:12 -0400 Subject: [PATCH 036/106] Catch errors when loading models --- src/hexdoc/graphics/loader.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index a29c7857..ee2d2657 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -51,7 +51,7 @@ def render_item(self, item_id: ResourceLocation): def render_model(self, model_id: ResourceLocation): model = self._load_model(model_id) - if isinstance(model, URL): + if not isinstance(model, BlockModel): return model for override_model in self._get_overrides(model): @@ -108,8 +108,11 @@ def _load_model(self, model_id: ResourceLocation): logger.debug(f"Cache hit: {model_id} = {result}") return result - _, model = BlockModel.load_and_resolve(self.loader, model_id) - return model + try: + _, model = BlockModel.load_and_resolve(self.loader, model_id) + return model + except Exception as e: + return self._fail(f"Failed to load model {model_id}: {e}") def _render_existing_texture(self, src: Path, output_id: ResourceLocation): fragment = self._get_fragment(output_id, src.suffix) From 49c64bfddcd1554a6f4c3bcd2b92c4c20fde5995 Mon Sep 17 00:00:00 2001 From: object-Object Date: Tue, 14 May 2024 01:12:32 -0400 Subject: [PATCH 037/106] Update render_model and render_models to use ModelLoader --- examples/model_rendering/.gitignore | 1 + src/hexdoc/cli/app.py | 52 +++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/examples/model_rendering/.gitignore b/examples/model_rendering/.gitignore index 852addd3..34d97dfc 100644 --- a/examples/model_rendering/.gitignore +++ b/examples/model_rendering/.gitignore @@ -1,5 +1,6 @@ # hexdoc out/ +renders/ .hexdoc*/ out.png diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index e08f2c0d..b33685f0 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -11,6 +11,8 @@ import typer from packaging.version import Version +from tqdm import tqdm +from tqdm.contrib.logging import logging_redirect_tqdm from typer import Argument, Option from yarl import URL @@ -20,10 +22,10 @@ from hexdoc.data.metadata import HexdocMetadata from hexdoc.data.sitemap import delete_updated_books, dump_sitemap, load_sitemap from hexdoc.graphics import DebugType, ModelRenderer +from hexdoc.graphics.loader import ModelLoader from hexdoc.jinja.render import create_jinja_env, get_templates, render_book from hexdoc.minecraft import I18n from hexdoc.minecraft.assets import AnimatedTexture, PNGTexture, TextureContext -from hexdoc.minecraft.assets.load_assets import render_block from hexdoc.patchouli import BookContext, FormattingContext from hexdoc.plugin import ModPluginWithBook from hexdoc.utils import git_root, setup_logging, write_to_path @@ -469,7 +471,14 @@ def render_model( item_size=size, ) as renderer, ): - renderer.render_model(ResourceLocation.from_str(model_id), output_path) + ml = ModelLoader( + loader=loader, + renderer=renderer, + site_url=URL(), + site_dir=output_path.parent, + ) + url = ml.render_model(ResourceLocation.from_str(model_id)) + print(f"Rendered model {model_id} to {url}.") @app.command() @@ -487,22 +496,37 @@ def render_models( site_url = URL(site_url_str or "") - props, pm, _, plugin = load_common_data(props_file, branch="") + props, pm, *_ = load_common_data(props_file, branch="") + + with ( + ModResourceLoader.load_all(props, pm, export=export_resources) as loader, + ModelRenderer(loader=loader) as renderer, + ): + ml = ModelLoader( + loader=loader, + renderer=renderer, + site_url=site_url, + site_dir=output_dir, + ) - with ModResourceLoader.load_all(props, pm, export=export_resources) as loader: if model_ids: - with ModelRenderer(loader=loader, output_dir=output_dir) as renderer: - for model_id in model_ids: - model_id = ResourceLocation.from_str(model_id) - render_block(model_id, renderer, site_url) + iterator = (ResourceLocation.from_str(model_id) for model_id in model_ids) else: - asset_loader = plugin.asset_loader( - loader=loader, - site_url=site_url, - asset_url=props.env.asset_url, - render_dir=output_dir, + iterator = ( + "item" / item_id + for _, item_id, _ in loader.find_resources( + "assets", + namespace="*", + folder="models/item", + internal_only=True, + ) ) - render_textures_and_export_metadata(loader, asset_loader) + + with logging_redirect_tqdm(): + bar = tqdm(iterator) + for model_id in bar: + bar.set_postfix_str(str(model_id)) + ml.render_model(model_id) logger.info("Done.") From db3f638cb6fd6644eab9738286e8c3aff59006f8 Mon Sep 17 00:00:00 2001 From: object-Object Date: Tue, 14 May 2024 01:32:06 -0400 Subject: [PATCH 038/106] Fix broken override loading --- examples/model_rendering/.gitignore | 2 +- .../minecraft/hexdoc/renders/item/chest.png | Bin 0 -> 775 bytes src/hexdoc/graphics/loader.py | 55 +++++++++--------- 3 files changed, 29 insertions(+), 28 deletions(-) create mode 100644 examples/model_rendering/resources/assets/minecraft/hexdoc/renders/item/chest.png diff --git a/examples/model_rendering/.gitignore b/examples/model_rendering/.gitignore index 34d97dfc..4c360a72 100644 --- a/examples/model_rendering/.gitignore +++ b/examples/model_rendering/.gitignore @@ -1,6 +1,6 @@ # hexdoc out/ -renders/ +/renders/ .hexdoc*/ out.png diff --git a/examples/model_rendering/resources/assets/minecraft/hexdoc/renders/item/chest.png b/examples/model_rendering/resources/assets/minecraft/hexdoc/renders/item/chest.png new file mode 100644 index 0000000000000000000000000000000000000000..eb7f7668ae1beb962a34aa3eac894335026c2e97 GIT binary patch literal 775 zcmV+i1Ni)jP)&0cLMseGEe}8{4n!~#GA0c$BM&ws z3O6SXH6#on7zsf^K{+`&OiWBxR#s6_QB6%vFE1}OH8n0F5ET;-6cP^*4hxK6CXHwv zrEMRgaVMZ^BdK^SlWQ%IVk0&%CoL!-DkdH*Cm(4^8E#G;Yey7lMHXB`6JSLhTtORK zJ{Vp<7EwJGBOe$e9~n$KA4)eJEG8Z*CLe-fE;218eO@9oE+!fm6CoWKLp2&TE+vj- zDKRW2FC-H!A`)t9YRk*ZEguXf9S>7F7&k5@4GRe@CLat72~|HH85R@T$OR+-0004W zQchCeEGWHmDjJII(7Z}6?}zgSs|{6jH5LAz>mVrpPs_K%|x;GSKm7Q|G@ zl=vX1U9t5FZwPfBel3VPYPfWS-hQ1LVOB{DX%YBrDUdSo+);xx;ZY0-cq0TQIfFqo0^P3*I}m(h<&mxg z2vb3G URL | None: if result := self._texture_cache.get(texture_id): @@ -99,9 +95,9 @@ def _fail(self, message: str): logger.error(message) return self.render_texture(MISSING_TEXTURE_ID) - def _get_overrides(self, model: BlockModel): - # TODO: implement (with _load_model) - yield model + def _get_overrides(self, model_id: ResourceLocation): + # TODO: implement (maybe) + yield model_id def _load_model(self, model_id: ResourceLocation): if result := self._model_cache.get(model_id): @@ -112,7 +108,7 @@ def _load_model(self, model_id: ResourceLocation): _, model = BlockModel.load_and_resolve(self.loader, model_id) return model except Exception as e: - return self._fail(f"Failed to load model {model_id}: {e}") + return self._fail(f"Failed to load model: {model_id}: {e}") def _render_existing_texture(self, src: Path, output_id: ResourceLocation): fragment = self._get_fragment(output_id, src.suffix) @@ -142,9 +138,11 @@ def _find_texture( "assets", namespace=texture_id.namespace, folder=folder, - glob=texture_id.path + ".{png,gif}", + glob=texture_id.path + ".*", allow_missing=True, ): + if path.suffix not in {".png", ".gif"}: + continue # after we find a match, only keep looking in the same resource dir # so we don't break the load order if prev_dir and prev_dir != resource_dir: @@ -158,33 +156,36 @@ def _find_texture( # model rendering strategies - def _from_props(self, model: BlockModel): - match self.props.textures.overrides.models.get(model.id): + def _from_props(self, model_id: ResourceLocation): + match self.props.textures.overrides.models.get(model_id): case ResourceLocation() as texture_id: _, src = self.loader.find_resource("assets", "", texture_id) - return self._render_existing_texture(src, model.id) + return self._render_existing_texture(src, model_id) case URL() as url: return url case None: - logger.debug(f"No props override for model: {model.id}") + logger.debug(f"No props override for model: {model_id}") return None def _from_resources(self, *, internal: bool): type_ = "internal" if internal else "external" - def inner(model: BlockModel): + def inner(model_id: ResourceLocation): if path := self._find_texture( - model.id, + model_id, folder="hexdoc/renders", internal=internal, ): - return self._render_existing_texture(path, model.id) - logger.debug(f"No {type_} rendered resource for model: {model.id}") + return self._render_existing_texture(path, model_id) + logger.debug(f"No {type_} rendered resource for model: {model_id}") inner.__name__ = f"_from_resources({internal=})" return inner - def _from_renderer(self, model: BlockModel): - fragment = self._get_fragment(model.id) + def _from_renderer(self, model_id: ResourceLocation): + model = self._load_model(model_id) + if not isinstance(model, BlockModel): + return None + fragment = self._get_fragment(model_id) suffix = self.renderer.render_model(model, self.site_dir / fragment) return self._fragment_to_url(fragment.with_suffix(suffix)) From 6a24b5e53d94b023fde6560f50507e6244ffc6a4 Mon Sep 17 00:00:00 2001 From: object-Object Date: Tue, 14 May 2024 01:42:05 -0400 Subject: [PATCH 039/106] Change default output format to gif, default output dir to out/ --- src/hexdoc/cli/app.py | 4 ++-- src/hexdoc/core/properties/textures.py | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index b33685f0..422f52f0 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -444,7 +444,7 @@ def render_model( model_id: str, *, props_file: PropsOption, - output_path: Annotated[Path, Option("--output", "-o")] = Path("out.png"), + output_dir: Annotated[Path, Option("--output", "-o")] = Path("out"), axes: bool = False, normals: bool = False, size: Optional[int] = None, @@ -475,7 +475,7 @@ def render_model( loader=loader, renderer=renderer, site_url=URL(), - site_dir=output_path.parent, + site_dir=output_dir, ) url = ml.render_model(ResourceLocation.from_str(model_id)) print(f"Rendered model {model_id} to {url}.") diff --git a/src/hexdoc/core/properties/textures.py b/src/hexdoc/core/properties/textures.py index 5658ab97..e2d8c95f 100644 --- a/src/hexdoc/core/properties/textures.py +++ b/src/hexdoc/core/properties/textures.py @@ -43,13 +43,14 @@ class AnimatedTexturesProps(StripHiddenModel): enabled: bool = True """If set to `False`, animated textures will be rendered as a PNG with the first frame of the animation.""" - format: AnimationFormat = AnimationFormat.APNG + format: AnimationFormat = AnimationFormat.GIF """Animated image output format. - `apng` (the default) is higher quality, but the file size is a bit larger. + `gif` (the default) produces smaller but lower quality files, and interpolated + textures may have issues with flickering. - `gif` produces smaller but lower quality files, and interpolated textures may have - issues with flickering. + `apng` is higher quality, but the file size is a bit larger, and some + platforms (eg. Discord) don't fully support it. """ max_frames: Annotated[int, Field(ge=0)] = 15 * 20 # 15 seconds * 20 tps """Maximum number of frames for animated textures (1 frame = 1 tick = 1/20 seconds). From ef92a552fb37db2dd8a731f25f988520c8faf915 Mon Sep 17 00:00:00 2001 From: object-Object Date: Mon, 20 May 2024 21:05:57 -0400 Subject: [PATCH 040/106] Disable exception locals again --- CHANGELOG.md | 6 ++++++ src/hexdoc/cli/utils/args.py | 2 ++ 2 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a30b4f30..0e4183f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Pydantic's HISTORY.md](https://github.com/pydantic/pydantic/blob/main/HISTORY.md), and this project *mostly* adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [UNRELEASED] + +### Changed + +* Disable showing local variables in Typer pretty exceptions, since it's a really absurd amount of output in many cases. Set a non-empty value for the environment variable `HEXDOC_TYPER_EXCEPTION_LOCALS` to reenable it, if you really want to. + ## `1!0.1.0a16` ### Added diff --git a/src/hexdoc/cli/utils/args.py b/src/hexdoc/cli/utils/args.py index 475617ec..c8d3f06d 100644 --- a/src/hexdoc/cli/utils/args.py +++ b/src/hexdoc/cli/utils/args.py @@ -1,5 +1,6 @@ import importlib import logging +import os from pathlib import Path from typing import Annotated @@ -28,6 +29,7 @@ "help_option_names": ["--help", "-h"], }, add_completion=False, + pretty_exceptions_show_locals=bool(os.getenv("HEXDOC_TYPER_EXCEPTION_LOCALS")), ) From efc0306a131b4b1c7ae5311bbd41a37609496707 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 17:05:20 -0400 Subject: [PATCH 041/106] Refactor code from TypeTaggedTemplate into TemplateModel --- src/hexdoc/model/__init__.py | 2 ++ src/hexdoc/model/tagged_union.py | 51 +++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/hexdoc/model/__init__.py b/src/hexdoc/model/__init__.py index 57d17ef8..14867fea 100644 --- a/src/hexdoc/model/__init__.py +++ b/src/hexdoc/model/__init__.py @@ -14,6 +14,7 @@ "ResourceModel", "StripHiddenModel", "TagValue", + "TemplateModel", "TypeTaggedTemplate", "TypeTaggedUnion", "ValidationContextModel", @@ -37,6 +38,7 @@ NoValue, NoValueType, TagValue, + TemplateModel, TypeTaggedTemplate, TypeTaggedUnion, ) diff --git a/src/hexdoc/model/tagged_union.py b/src/hexdoc/model/tagged_union.py index 50ba3db7..83f9ee50 100644 --- a/src/hexdoc/model/tagged_union.py +++ b/src/hexdoc/model/tagged_union.py @@ -343,26 +343,23 @@ def _tag_value_type(cls) -> type[Any]: return ResourceLocation -class TypeTaggedTemplate(TypeTaggedUnion, ABC, type=None): - __template_id: ClassVar[ResourceLocation] +class TemplateModel(HexdocModel, ABC): + __template_id: ClassVar[ResourceLocation | None] = None def __init_subclass__( cls, *, - type: str | InheritType | None = Inherit, - template_type: str | None = None, + template_type: str | ResourceLocation | None = None, **kwargs: Unpack[ConfigDict], ) -> None: - super().__init_subclass__(type=type, **kwargs) - - # jinja template path - if template_type is not None: - template_id = ResourceLocation.from_str(template_type) - else: - template_id = cls.type - - if template_id: - cls.__template_id = template_id + super().__init_subclass__(**kwargs) + match template_type: + case str(): + cls.__template_id = ResourceLocation.from_str(template_type) + case ResourceLocation(): + cls.__template_id = template_type + case None: + pass @classproperty @classmethod @@ -376,4 +373,30 @@ def template(cls) -> str: @classproperty @classmethod def template_id(cls): + assert cls.__template_id is not None, f"Template id not initialized: {cls}" return cls.__template_id + + +class TypeTaggedTemplate(TypeTaggedUnion, TemplateModel, ABC, type=None): + def __init_subclass__( + cls, + *, + type: str | InheritType | None = Inherit, + template_type: str | ResourceLocation | None = None, + **kwargs: Unpack[ConfigDict], + ) -> None: + if template_type is None: + match type: + case str(): + template_type = type + case InheritType() if isinstance(cls.type, ResourceLocation): + template_type = cls.type + case _: + pass + + super().__init_subclass__( + type=type, + # pyright doesn't seem to understand multiple inheritance here + template_type=template_type, # pyright: ignore[reportCallIssue] + **kwargs, + ) From 0acf8de67cf81793ee657432d01370ddac3567ab Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 17:26:37 -0400 Subject: [PATCH 042/106] Allow explicitly inheriting template id from superclass --- src/hexdoc/core/resource.py | 2 ++ src/hexdoc/model/tagged_union.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/hexdoc/core/resource.py b/src/hexdoc/core/resource.py index a64e249b..27affb19 100644 --- a/src/hexdoc/core/resource.py +++ b/src/hexdoc/core/resource.py @@ -198,6 +198,8 @@ def match(self, pattern: Self) -> bool: return fnmatch(str(self), str(pattern)) def template_path(self, type: str, folder: str = "") -> str: + """Returns a Jinja template path in the format + `{type}/{namespace}/{folder}/{path}`.""" return self.file_path_stub(type, folder, assume_json=False).as_posix() def file_path_stub( diff --git a/src/hexdoc/model/tagged_union.py b/src/hexdoc/model/tagged_union.py index 83f9ee50..1af31c00 100644 --- a/src/hexdoc/model/tagged_union.py +++ b/src/hexdoc/model/tagged_union.py @@ -344,21 +344,21 @@ def _tag_value_type(cls) -> type[Any]: class TemplateModel(HexdocModel, ABC): - __template_id: ClassVar[ResourceLocation | None] = None + _template_id: ClassVar[ResourceLocation | None] = None def __init_subclass__( cls, *, - template_type: str | ResourceLocation | None = None, + template_type: str | ResourceLocation | InheritType | None = None, **kwargs: Unpack[ConfigDict], ) -> None: super().__init_subclass__(**kwargs) match template_type: case str(): - cls.__template_id = ResourceLocation.from_str(template_type) - case ResourceLocation(): - cls.__template_id = template_type - case None: + cls._template_id = ResourceLocation.from_str(template_type) + case ResourceLocation() | None: + cls._template_id = template_type + case InheritType(): pass @classproperty @@ -373,8 +373,8 @@ def template(cls) -> str: @classproperty @classmethod def template_id(cls): - assert cls.__template_id is not None, f"Template id not initialized: {cls}" - return cls.__template_id + assert cls._template_id is not None, f"Template id not initialized: {cls}" + return cls._template_id class TypeTaggedTemplate(TypeTaggedUnion, TemplateModel, ABC, type=None): From 6d0d831b566c573ae54f7925ba976a17e31a32af Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 18:27:59 -0400 Subject: [PATCH 043/106] Refactor InternallyTaggedUnion resolution into UnionModel --- src/hexdoc/model/__init__.py | 2 + src/hexdoc/model/tagged_union.py | 189 +++++++++++++++++++------------ 2 files changed, 118 insertions(+), 73 deletions(-) diff --git a/src/hexdoc/model/__init__.py b/src/hexdoc/model/__init__.py index 14867fea..b127847a 100644 --- a/src/hexdoc/model/__init__.py +++ b/src/hexdoc/model/__init__.py @@ -17,6 +17,7 @@ "TemplateModel", "TypeTaggedTemplate", "TypeTaggedUnion", + "UnionModel", "ValidationContextModel", "init_context", ] @@ -41,5 +42,6 @@ TemplateModel, TypeTaggedTemplate, TypeTaggedUnion, + UnionModel, ) from .types import Color diff --git a/src/hexdoc/model/tagged_union.py b/src/hexdoc/model/tagged_union.py index 1af31c00..17e0d1b0 100644 --- a/src/hexdoc/model/tagged_union.py +++ b/src/hexdoc/model/tagged_union.py @@ -4,7 +4,15 @@ from abc import ABC, abstractmethod from collections import defaultdict -from typing import Any, ClassVar, Generator, Self, Unpack +from typing import ( + Any, + ClassVar, + Generator, + Iterable, + LiteralString, + Self, + Unpack, +) import more_itertools from pydantic import ( @@ -40,7 +48,96 @@ _is_loaded = False -class InternallyTaggedUnion(HexdocModel): +class UnionModel(HexdocModel): + @classmethod + def _resolve_union( + cls, + value: Any, + info: ValidationInfo, + *, + model_types: Iterable[type[Self]], + allow_ambiguous: bool, + error_name: LiteralString = "HexdocUnionMatchError", + error_text: Iterable[LiteralString] = [], + error_data: dict[str, Any] = {}, + ) -> Self: + # try all the types + exceptions: list[InitErrorDetails] = [] + matches: dict[type[Self], Self] = {} + + for model_type in model_types: + try: + result = matches[model_type] = model_type.model_validate( + value, + context=info.context, + ) + if allow_ambiguous: + return result + except Exception as e: + exceptions.append( + InitErrorDetails( + type=PydanticCustomError( + error_name, + "{exception_class}: {exception}", + { + "exception_class": e.__class__.__name__, + "exception": str(e), + }, + ), + loc=( + cls.__name__, + model_type.__name__, + ), + input=value, + ) + ) + + # ensure we only matched one + # if allow_ambiguous is True, we should have returned a value already + match len(matches): + case 1: + return matches.popitem()[1] + case x if x > 1: + ambiguous_types = ", ".join(str(t) for t in matches.keys()) + reason = f"Ambiguous union match: {ambiguous_types}" + case _: + reason = "No match found" + + # something went wrong, raise an exception + error = PydanticCustomError( + f"{error_name}Group", + "\n ".join( + ( + "Failed to match union {class_name}: {reason}", + "Types: {types}", + "Value: {value}", + *error_text, + ) + ), + { + "class_name": str(cls), + "reason": reason, + "types": ", ".join(str(t) for t in model_types), + "value": repr(value), + **error_data, + }, + ) + + if exceptions: + exceptions.insert( + 0, + InitErrorDetails( + type=error, + loc=(cls.__name__,), + input=value, + ), + ) + raise ValidationError.from_exception_data(error_name, exceptions) + + raise RuntimeError(str(error)) + + +class InternallyTaggedUnion(UnionModel): """Implements [internally tagged unions](https://serde.rs/enum-representations.html#internally-tagged) using the [Registry pattern](https://charlesreid1.github.io/python-patterns-the-registry.html). @@ -153,79 +250,25 @@ def _resolve_from_dict( if tag_types is None: raise TypeError(f"Unhandled tag: {tag_key}={tag_value} for {cls}: {data}") - # try all the types - exceptions: list[InitErrorDetails] = [] - matches: dict[type[Self], Self] = {} - - for inner_type in tag_types: - try: - matches[inner_type] = inner_type.model_validate( - data, context=info.context - ) - except Exception as e: - exceptions.append( - InitErrorDetails( - type=PydanticCustomError( - "TaggedUnionMatchError", - "{exception_class}: {exception}", - { - "exception_class": e.__class__.__name__, - "exception": str(e), - }, - ), - loc=( - cls.__name__, - inner_type.__name__, - ), - input=data, - ) - ) - - # ensure we only matched one - match len(matches): - case 1: - return matches.popitem()[1] - case x if x > 1: - ambiguous_types = ", ".join(str(t) for t in matches.keys()) - reason = f"Ambiguous union match: {ambiguous_types}" - case _: - reason = "No match found" - - # something went wrong, raise an exception - error = PydanticCustomError( - "TaggedUnionMatchErrorGroup", - ( - "Failed to match tagged union {class_name}: {reason}\n" - " Tag: {tag_key}={tag_value}\n" - " Types: {types}\n" - " Data: {data}" - ), - { - "class_name": str(cls), - "reason": reason, - "tag_key": cls._tag_key, - "tag_value": tag_value, - "types": ", ".join(str(t) for t in tag_types), - "data": repr(data), - }, - ) - - if exceptions: + try: + return cls._resolve_union( + data, + info, + model_types=tag_types, + allow_ambiguous=False, + error_name="TaggedUnionMatchError", + error_text=[ + "Tag: {tag_key}={tag_value}", + ], + error_data={ + "tag_key": cls._tag_key, + "tag_value": tag_value, + }, + ) + except Exception: if _RESOLVED in data: data.pop(_RESOLVED) # avoid interfering with other types - exceptions.insert( - 0, - InitErrorDetails( - type=error, - loc=(cls.__name__,), - input=data, - ), - ) - raise ValidationError.from_exception_data( - "TaggedUnionMatchError", exceptions - ) - - raise RuntimeError(str(error)) + raise @model_validator(mode="before") def _pop_temporary_keys(cls, value: dict[Any, Any] | Any): From 14196584feabc6632cf232f64253ec519ce2f94a Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 18:42:51 -0400 Subject: [PATCH 044/106] Convert PluginManager to a dataclass --- src/hexdoc/plugin/manager.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/hexdoc/plugin/manager.py b/src/hexdoc/plugin/manager.py index 47c54404..24c3b625 100644 --- a/src/hexdoc/plugin/manager.py +++ b/src/hexdoc/plugin/manager.py @@ -1,7 +1,7 @@ from __future__ import annotations import importlib -from dataclasses import dataclass +from dataclasses import InitVar, dataclass, field from importlib.resources import Package from pathlib import Path from types import ModuleType @@ -87,21 +87,20 @@ class _NoCallTypedHookCaller(TypedHookCaller[_P, None]): def __call__(self, *args: _P.args, **kwargs: _P.kwargs) -> Never: ... -# TODO: convert to dataclass +@dataclass class PluginManager(ValidationContext): """Custom hexdoc plugin manager with helpers and stronger typing.""" - def __init__(self, branch: str, props: Properties, load: bool = True) -> None: - """Initialize the hexdoc plugin manager. + branch: str + props: Properties + load: InitVar[bool] = True + """If true (the default), calls `init_entrypoints` and `init_mod_plugins`.""" - If `load` is true (the default), calls `init_entrypoints` and `init_mod_plugins`. - """ - self.branch = branch - self.props = props - self.inner = pluggy.PluginManager(HEXDOC_PROJECT_NAME) - self.mod_plugins: dict[str, ModPlugin] = {} - self.book_plugins: dict[str, BookPlugin[Any]] = {} + mod_plugins: dict[str, ModPlugin] = field(default_factory=dict) + book_plugins: dict[str, BookPlugin[Any]] = field(default_factory=dict) + def __post_init__(self, load: bool): + self.inner = pluggy.PluginManager(HEXDOC_PROJECT_NAME) self.inner.add_hookspecs(PluginSpec) if load: self.init_entrypoints() From 8860cfffa52511cc56d8207d5b1c34fc5aad6d9b Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 19:42:03 -0400 Subject: [PATCH 045/106] Implement new HexdocImage types --- .../assets/hexdoc/textures/item/tag.png | Bin 0 -> 131 bytes src/hexdoc/_hooks.py | 4 + src/hexdoc/graphics/__init__.py | 4 + src/hexdoc/graphics/loader.py | 36 +++-- src/hexdoc/graphics/validators.py | 145 ++++++++++++++++++ src/hexdoc/model/tagged_union.py | 6 +- src/hexdoc/plugin/manager.py | 3 + src/hexdoc/plugin/mod_plugin.py | 5 + 8 files changed, 186 insertions(+), 17 deletions(-) create mode 100644 src/hexdoc/_export/resources/assets/hexdoc/textures/item/tag.png create mode 100644 src/hexdoc/graphics/validators.py diff --git a/src/hexdoc/_export/resources/assets/hexdoc/textures/item/tag.png b/src/hexdoc/_export/resources/assets/hexdoc/textures/item/tag.png new file mode 100644 index 0000000000000000000000000000000000000000..8c1ef45e1779fb6c4a7ef85b302f29dfbdfc9af5 GIT binary patch literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`oCO|{#S9F3${@^GvDCf{C}`^G z;uvCaIypgNibHJd-~GFG{i=_tNjc!MGF3$SK*t-OAd`E0Dko3W(v$e%Aj8WXRoS?X Zfx%>xWTWa4XCa^g44$rjF6*2UngCyzCM*B| literal 0 HcmV?d00001 diff --git a/src/hexdoc/_hooks.py b/src/hexdoc/_hooks.py index fe39c04e..e4c0042d 100644 --- a/src/hexdoc/_hooks.py +++ b/src/hexdoc/_hooks.py @@ -9,6 +9,7 @@ import hexdoc from hexdoc import HEXDOC_MODID, VERSION from hexdoc.core import IsVersion, ModResourceLoader, ResourceLocation +from hexdoc.graphics.validators import SingleItemImage from hexdoc.minecraft.recipe import ( ingredients as minecraft_ingredients, recipes as minecraft_recipes, @@ -130,6 +131,9 @@ def default_rendered_templates_v2( return templates + def item_image_types(self): + return SingleItemImage + class PatchouliBookPlugin(BookPlugin[Book]): @property diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index 24f12232..51360e46 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -1,11 +1,15 @@ __all__ = [ "DebugType", + "ItemImage", "ModelLoader", "ModelRenderer", "ModelTexture", + "TagImage", + "TextureImage", ] from .loader import ModelLoader from .renderer import ModelRenderer from .texture import ModelTexture from .utils import DebugType +from .validators import ItemImage, TagImage, TextureImage diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index 8c2a604a..3f5ec9ee 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -6,6 +6,7 @@ from yarl import URL from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.core.resource import BaseResourceLocation from hexdoc.minecraft.model import BlockModel from hexdoc.utils import ValidationContext @@ -15,10 +16,14 @@ logger = logging.getLogger(__name__) MISSING_TEXTURE_ID = ResourceLocation("hexdoc", "textures/item/missing.png") +TAG_TEXTURE_ID = ResourceLocation("hexdoc", "textures/item/tag.png") -ModelLoaderStrategy = Callable[[ResourceLocation], URL | None] +ModelLoaderResult = tuple[URL, BlockModel | None] +ModelLoaderStrategy = Callable[[ResourceLocation], ModelLoaderResult | None] + +# TODO: rename to ImageLoader @dataclass(kw_only=True) class ModelLoader(ValidationContext): loader: ModResourceLoader @@ -29,7 +34,7 @@ class ModelLoader(ValidationContext): def __post_init__(self): # TODO: see cache comment in hexdoc.graphics.texture # (though it's less of an issue here since these aren't globals) - self._model_cache = dict[ResourceLocation, URL]() + self._model_cache = dict[ResourceLocation, ModelLoaderResult]() self._texture_cache = dict[ResourceLocation, URL]() self._strategies: list[ModelLoaderStrategy] = [ @@ -43,13 +48,14 @@ def __post_init__(self): def props(self): return self.loader.props - def render_block(self, block_id: ResourceLocation): - return self.render_model("block" / block_id) + def render_block(self, block_id: BaseResourceLocation) -> ModelLoaderResult: + return self.render_model("block" / block_id.id) - def render_item(self, item_id: ResourceLocation): - return self.render_model("item" / item_id) + def render_item(self, item_id: BaseResourceLocation) -> ModelLoaderResult: + return self.render_model("item" / item_id.id) - def render_model(self, model_id: ResourceLocation): + def render_model(self, model_id: BaseResourceLocation) -> ModelLoaderResult: + model_id = model_id.id logger.debug(f"Rendering model: {model_id}") for override_id in self._get_overrides(model_id): logger.debug(f"Attempting override: {override_id}") @@ -67,9 +73,9 @@ def render_model(self, model_id: ResourceLocation): exc_info=True, ) - return self._fail(f"Failed to render model: {model_id}") + return self._fail(f"Failed to render model: {model_id}"), None - def render_texture(self, texture_id: ResourceLocation) -> URL | None: + def render_texture(self, texture_id: ResourceLocation) -> URL: if result := self._texture_cache.get(texture_id): return result @@ -93,7 +99,9 @@ def _fail(self, message: str): if self.props.textures.strict: raise ValueError(message) logger.error(message) - return self.render_texture(MISSING_TEXTURE_ID) + missing = self.render_texture(MISSING_TEXTURE_ID) + assert missing is not None + return missing def _get_overrides(self, model_id: ResourceLocation): # TODO: implement (maybe) @@ -160,9 +168,9 @@ def _from_props(self, model_id: ResourceLocation): match self.props.textures.overrides.models.get(model_id): case ResourceLocation() as texture_id: _, src = self.loader.find_resource("assets", "", texture_id) - return self._render_existing_texture(src, model_id) + return self._render_existing_texture(src, model_id), None case URL() as url: - return url + return url, None case None: logger.debug(f"No props override for model: {model_id}") return None @@ -176,7 +184,7 @@ def inner(model_id: ResourceLocation): folder="hexdoc/renders", internal=internal, ): - return self._render_existing_texture(path, model_id) + return self._render_existing_texture(path, model_id), None logger.debug(f"No {type_} rendered resource for model: {model_id}") inner.__name__ = f"_from_resources({internal=})" @@ -188,4 +196,4 @@ def _from_renderer(self, model_id: ResourceLocation): return None fragment = self._get_fragment(model_id) suffix = self.renderer.render_model(model, self.site_dir / fragment) - return self._fragment_to_url(fragment.with_suffix(suffix)) + return self._fragment_to_url(fragment.with_suffix(suffix)), model diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py new file mode 100644 index 00000000..9279e248 --- /dev/null +++ b/src/hexdoc/graphics/validators.py @@ -0,0 +1,145 @@ +from __future__ import annotations + +from abc import ABC, abstractmethod +from typing import ( + Any, + Generic, + Unpack, +) + +from copier import ConfigDict +from pydantic import ( + Field, + PrivateAttr, + ValidationInfo, + field_validator, + model_validator, +) +from typing_extensions import TypeVar, override + +from hexdoc.core import BaseResourceLocation, ItemStack, ResourceLocation +from hexdoc.minecraft import I18n, LocalizedStr +from hexdoc.minecraft.model import BlockModel +from hexdoc.model import ( + InlineItemModel, + InlineModel, + TemplateModel, + UnionModel, +) +from hexdoc.plugin import PluginManager +from hexdoc.utils import Inherit, InheritType, PydanticURL, classproperty + +from .loader import TAG_TEXTURE_ID, ModelLoader + +_T_ResourceLocation = TypeVar( + "_T_ResourceLocation", + bound=BaseResourceLocation, + default=ResourceLocation, +) + + +class HexdocImage(TemplateModel, Generic[_T_ResourceLocation], ABC): + """An image that can be rendered in a hexdoc web book.""" + + id: _T_ResourceLocation + + _name: LocalizedStr = PrivateAttr() + + # change default from None to Inherit + def __init_subclass__( + cls, + *, + template_type: str | ResourceLocation | InheritType | None = Inherit, + **kwargs: Unpack[ConfigDict], + ): + super().__init_subclass__(template_type=template_type, **kwargs) + + @classproperty + @classmethod + @override + def template(cls): + return cls.template_id.template_path("images") + + @property + def name(self): + return self._name + + @abstractmethod + def _get_name(self, info: ValidationInfo) -> LocalizedStr: ... + + @model_validator(mode="after") + def _set_name(self, info: ValidationInfo): + self._name = self._get_name(info) + return self + + +class URLImage(HexdocImage[_T_ResourceLocation], template_id="hexdoc:single"): + url: PydanticURL + pixelated: bool = True + + +class TextureImage(URLImage[ResourceLocation], InlineModel): + @override + @classmethod + def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: + url = ModelLoader.of(context).render_texture(id) + return cls(id=id, url=url) + + @override + def _get_name(self, info: ValidationInfo): + return I18n.of(info).localize_texture(self.id) + + +class ItemImage(HexdocImage[ItemStack], InlineItemModel, UnionModel, ABC): + @override + @abstractmethod + @classmethod + def load_id(cls, item: ItemStack, context: dict[str, Any]) -> Any: + pm = PluginManager.of(context) + return cls._resolve_union( + item, + context, + model_types=pm.item_image_types, + allow_ambiguous=True, + ) + + +class SingleItemImage(URLImage[ItemStack], ItemImage): + model: BlockModel | None + + @override + @classmethod + def load_id(cls, item: ItemStack, context: dict[str, Any]) -> Any: + url, model = ModelLoader.of(context).render_item(item) + return cls(id=item, url=url, model=model) + + @override + def _get_name(self, info: ValidationInfo): + return I18n.of(info).localize_item(self.id) + + +class CyclingImage(HexdocImage[_T_ResourceLocation], template_id="hexdoc:cycling"): + images: list[HexdocImage] = Field(min_length=1) + + @override + def _get_name(self, info: ValidationInfo): + return self.images[0].name + + +class TagImage(URLImage[ResourceLocation], InlineModel): + @override + @classmethod + def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: + # TODO: load images for all the items in the tag? + url = ModelLoader.of(context).render_texture(TAG_TEXTURE_ID) + return cls(id=id, url=url) + + @override + def _get_name(self, info: ValidationInfo): + return I18n.of(info).localize_item_tag(self.id) + + @field_validator("id", mode="after") + @classmethod + def _validate_id(cls, id: ResourceLocation): + assert id.is_tag, f"Expected tag id, got {id}" + return id diff --git a/src/hexdoc/model/tagged_union.py b/src/hexdoc/model/tagged_union.py index 17e0d1b0..c6569ee6 100644 --- a/src/hexdoc/model/tagged_union.py +++ b/src/hexdoc/model/tagged_union.py @@ -53,7 +53,7 @@ class UnionModel(HexdocModel): def _resolve_union( cls, value: Any, - info: ValidationInfo, + context: dict[str, Any] | None, *, model_types: Iterable[type[Self]], allow_ambiguous: bool, @@ -69,7 +69,7 @@ def _resolve_union( try: result = matches[model_type] = model_type.model_validate( value, - context=info.context, + context=context, ) if allow_ambiguous: return result @@ -253,7 +253,7 @@ def _resolve_from_dict( try: return cls._resolve_union( data, - info, + info.context, model_types=tag_types, allow_ambiguous=False, error_name="TaggedUnionMatchError", diff --git a/src/hexdoc/plugin/manager.py b/src/hexdoc/plugin/manager.py index 24c3b625..4d6f43d4 100644 --- a/src/hexdoc/plugin/manager.py +++ b/src/hexdoc/plugin/manager.py @@ -29,6 +29,7 @@ if TYPE_CHECKING: from hexdoc.core import Properties, ResourceLocation + from hexdoc.graphics.validators import ItemImage from hexdoc.minecraft import I18n from hexdoc.patchouli import FormatTree @@ -98,6 +99,7 @@ class PluginManager(ValidationContext): mod_plugins: dict[str, ModPlugin] = field(default_factory=dict) book_plugins: dict[str, BookPlugin[Any]] = field(default_factory=dict) + item_image_types: list[type[ItemImage]] = field(default_factory=list) def __post_init__(self, load: bool): self.inner = pluggy.PluginManager(HEXDOC_PROJECT_NAME) @@ -128,6 +130,7 @@ def _init_mod_plugins(self): ) ): self.mod_plugins[plugin.modid] = plugin + self.item_image_types += flatten([plugin.item_image_types()]) def register(self, plugin: Any, name: str | None = None): self.inner.register(plugin, name) diff --git a/src/hexdoc/plugin/mod_plugin.py b/src/hexdoc/plugin/mod_plugin.py index 4a04e294..9b1ba7ad 100644 --- a/src/hexdoc/plugin/mod_plugin.py +++ b/src/hexdoc/plugin/mod_plugin.py @@ -16,6 +16,7 @@ if TYPE_CHECKING: from hexdoc.core import ModResourceLoader, Properties + from hexdoc.graphics.validators import ItemImage from hexdoc.minecraft.assets import HexdocAssetLoader DefaultRenderedTemplates = Mapping[ @@ -140,6 +141,10 @@ def update_jinja_env(self, env: SandboxedEnvironment) -> None: rendering the book. """ + def item_image_types(self) -> HookReturn[type[ItemImage[Any]]]: + """List of `ModelImage` types to attempt when loading a block/item model.""" + return [] + # utils def site_path(self, versioned: bool): From adf001da6a1dc007b6de1d1cfbca3d1e615af938 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 19:43:59 -0400 Subject: [PATCH 046/106] Rename ModelLoader to ImageLoader --- src/hexdoc/cli/app.py | 10 +++++----- src/hexdoc/graphics/__init__.py | 4 ++-- src/hexdoc/graphics/loader.py | 19 +++++++++---------- src/hexdoc/graphics/validators.py | 8 ++++---- 4 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 422f52f0..adfa857a 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -22,7 +22,7 @@ from hexdoc.data.metadata import HexdocMetadata from hexdoc.data.sitemap import delete_updated_books, dump_sitemap, load_sitemap from hexdoc.graphics import DebugType, ModelRenderer -from hexdoc.graphics.loader import ModelLoader +from hexdoc.graphics.loader import ImageLoader from hexdoc.jinja.render import create_jinja_env, get_templates, render_book from hexdoc.minecraft import I18n from hexdoc.minecraft.assets import AnimatedTexture, PNGTexture, TextureContext @@ -471,13 +471,13 @@ def render_model( item_size=size, ) as renderer, ): - ml = ModelLoader( + image_loader = ImageLoader( loader=loader, renderer=renderer, site_url=URL(), site_dir=output_dir, ) - url = ml.render_model(ResourceLocation.from_str(model_id)) + url = image_loader.render_model(ResourceLocation.from_str(model_id)) print(f"Rendered model {model_id} to {url}.") @@ -502,7 +502,7 @@ def render_models( ModResourceLoader.load_all(props, pm, export=export_resources) as loader, ModelRenderer(loader=loader) as renderer, ): - ml = ModelLoader( + image_loader = ImageLoader( loader=loader, renderer=renderer, site_url=site_url, @@ -526,7 +526,7 @@ def render_models( bar = tqdm(iterator) for model_id in bar: bar.set_postfix_str(str(model_id)) - ml.render_model(model_id) + image_loader.render_model(model_id) logger.info("Done.") diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index 51360e46..e0e9f759 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -1,14 +1,14 @@ __all__ = [ "DebugType", + "ImageLoader", "ItemImage", - "ModelLoader", "ModelRenderer", "ModelTexture", "TagImage", "TextureImage", ] -from .loader import ModelLoader +from .loader import ImageLoader from .renderer import ModelRenderer from .texture import ModelTexture from .utils import DebugType diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index 3f5ec9ee..51d4dbda 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -18,14 +18,13 @@ MISSING_TEXTURE_ID = ResourceLocation("hexdoc", "textures/item/missing.png") TAG_TEXTURE_ID = ResourceLocation("hexdoc", "textures/item/tag.png") -ModelLoaderResult = tuple[URL, BlockModel | None] +LoadedModel = tuple[URL, BlockModel | None] -ModelLoaderStrategy = Callable[[ResourceLocation], ModelLoaderResult | None] +ModelLoaderStrategy = Callable[[ResourceLocation], LoadedModel | None] -# TODO: rename to ImageLoader @dataclass(kw_only=True) -class ModelLoader(ValidationContext): +class ImageLoader(ValidationContext): loader: ModResourceLoader renderer: ModelRenderer site_dir: Path @@ -34,10 +33,10 @@ class ModelLoader(ValidationContext): def __post_init__(self): # TODO: see cache comment in hexdoc.graphics.texture # (though it's less of an issue here since these aren't globals) - self._model_cache = dict[ResourceLocation, ModelLoaderResult]() + self._model_cache = dict[ResourceLocation, LoadedModel]() self._texture_cache = dict[ResourceLocation, URL]() - self._strategies: list[ModelLoaderStrategy] = [ + self._model_strategies: list[ModelLoaderStrategy] = [ self._from_props, self._from_resources(internal=True), self._from_renderer, @@ -48,18 +47,18 @@ def __post_init__(self): def props(self): return self.loader.props - def render_block(self, block_id: BaseResourceLocation) -> ModelLoaderResult: + def render_block(self, block_id: BaseResourceLocation) -> LoadedModel: return self.render_model("block" / block_id.id) - def render_item(self, item_id: BaseResourceLocation) -> ModelLoaderResult: + def render_item(self, item_id: BaseResourceLocation) -> LoadedModel: return self.render_model("item" / item_id.id) - def render_model(self, model_id: BaseResourceLocation) -> ModelLoaderResult: + def render_model(self, model_id: BaseResourceLocation) -> LoadedModel: model_id = model_id.id logger.debug(f"Rendering model: {model_id}") for override_id in self._get_overrides(model_id): logger.debug(f"Attempting override: {override_id}") - for strategy in self._strategies: + for strategy in self._model_strategies: logger.debug(f"Attempting model strategy: {strategy.__name__}") try: if result := strategy(override_id): diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 9279e248..99dd64e3 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -29,7 +29,7 @@ from hexdoc.plugin import PluginManager from hexdoc.utils import Inherit, InheritType, PydanticURL, classproperty -from .loader import TAG_TEXTURE_ID, ModelLoader +from .loader import TAG_TEXTURE_ID, ImageLoader _T_ResourceLocation = TypeVar( "_T_ResourceLocation", @@ -82,7 +82,7 @@ class TextureImage(URLImage[ResourceLocation], InlineModel): @override @classmethod def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: - url = ModelLoader.of(context).render_texture(id) + url = ImageLoader.of(context).render_texture(id) return cls(id=id, url=url) @override @@ -110,7 +110,7 @@ class SingleItemImage(URLImage[ItemStack], ItemImage): @override @classmethod def load_id(cls, item: ItemStack, context: dict[str, Any]) -> Any: - url, model = ModelLoader.of(context).render_item(item) + url, model = ImageLoader.of(context).render_item(item) return cls(id=item, url=url, model=model) @override @@ -131,7 +131,7 @@ class TagImage(URLImage[ResourceLocation], InlineModel): @classmethod def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: # TODO: load images for all the items in the tag? - url = ModelLoader.of(context).render_texture(TAG_TEXTURE_ID) + url = ImageLoader.of(context).render_texture(TAG_TEXTURE_ID) return cls(id=id, url=url) @override From c04f0b4e417237f376218a91318d8b2e0c48a427 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 20:50:57 -0400 Subject: [PATCH 047/106] Add ImageLoader to validation context --- src/hexdoc/cli/app.py | 41 ++++++++++++++++---- src/hexdoc/cli/utils/load.py | 3 ++ src/hexdoc/graphics/validators.py | 25 ++++-------- src/hexdoc/minecraft/assets/load_assets.py | 3 +- src/hexdoc/model/tagged_union.py | 10 ++--- test/integration/test_extend_book.py | 44 +++++++++++++++++++++- test/integration/test_modpack.py | 24 +++++++++++- 7 files changed, 116 insertions(+), 34 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index adfa857a..59713160 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -112,18 +112,21 @@ def repl(*, props_file: PropsOption): try: props, pm, book_plugin, plugin = load_common_data(props_file, branch="") - repl_locals |= dict( - props=props, - pm=pm, - plugin=plugin, - ) loader = ModResourceLoader.load_all( props, pm, export=False, ) - repl_locals["loader"] = loader + + renderer = ModelRenderer(loader=loader) + + image_loader = ImageLoader( + loader=loader, + renderer=renderer, + site_url=URL(), + site_dir=Path("out"), + ) if props.book_id: book_id, book_data = book_plugin.load_book_data(props.book_id, loader) @@ -137,7 +140,16 @@ def repl(*, props_file: PropsOption): )[props.default_lang] all_metadata = loader.load_metadata(model_type=HexdocMetadata) - repl_locals["all_metadata"] = all_metadata + + repl_locals |= dict( + props=props, + pm=pm, + plugin=plugin, + loader=loader, + renderer=renderer, + image_loader=image_loader, + all_metadata=all_metadata, + ) if book_id and book_data: context = init_context( @@ -145,6 +157,7 @@ def repl(*, props_file: PropsOption): book_data=book_data, pm=pm, loader=loader, + image_loader=image_loader, i18n=i18n, all_metadata=all_metadata, ) @@ -188,7 +201,10 @@ def build( output_dir /= props.env.hexdoc_subdirectory logger.info("Exporting resources.") - with ModResourceLoader.clean_and_load_all(props, pm, export=True) as loader: + with ( + ModResourceLoader.clean_and_load_all(props, pm, export=True) as loader, + ModelRenderer(loader=loader) as renderer, + ): site_path = plugin.site_path(versioned=release) site_dir = output_dir / site_path @@ -198,6 +214,14 @@ def build( asset_url=props.env.asset_url, render_dir=site_dir, ) + asset_loader.default_renderer = renderer + + image_loader = ImageLoader( + loader=loader, + renderer=renderer, + site_dir=site_dir, + site_url=URL(*site_path.parts), + ) all_metadata = render_textures_and_export_metadata(loader, asset_loader) @@ -221,6 +245,7 @@ def build( book_data=book_data, pm=pm, loader=loader, + image_loader=image_loader, i18n=i18n, all_metadata=all_metadata, ) diff --git a/src/hexdoc/cli/utils/load.py b/src/hexdoc/cli/utils/load.py index 512a67d3..69fd35bd 100644 --- a/src/hexdoc/cli/utils/load.py +++ b/src/hexdoc/cli/utils/load.py @@ -13,6 +13,7 @@ ResourceLocation, ) from hexdoc.data import HexdocMetadata, load_metadata_textures +from hexdoc.graphics.loader import ImageLoader from hexdoc.minecraft import I18n, Tag from hexdoc.minecraft.assets import ( AnimatedTexture, @@ -123,6 +124,7 @@ def init_context( book_data: dict[str, Any], pm: PluginManager, loader: ModResourceLoader, + image_loader: ImageLoader, i18n: I18n, all_metadata: dict[str, HexdocMetadata], ): @@ -134,6 +136,7 @@ def init_context( props, pm, loader, + image_loader, i18n, TextureContext( textures=load_metadata_textures(all_metadata), diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 99dd64e3..76d4534f 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -1,13 +1,8 @@ from __future__ import annotations from abc import ABC, abstractmethod -from typing import ( - Any, - Generic, - Unpack, -) +from typing import Any, Generic -from copier import ConfigDict from pydantic import ( Field, PrivateAttr, @@ -17,8 +12,8 @@ ) from typing_extensions import TypeVar, override -from hexdoc.core import BaseResourceLocation, ItemStack, ResourceLocation -from hexdoc.minecraft import I18n, LocalizedStr +from hexdoc.core import ItemStack, ResourceLocation +from hexdoc.minecraft.i18n import I18n, LocalizedStr from hexdoc.minecraft.model import BlockModel from hexdoc.model import ( InlineItemModel, @@ -31,11 +26,7 @@ from .loader import TAG_TEXTURE_ID, ImageLoader -_T_ResourceLocation = TypeVar( - "_T_ResourceLocation", - bound=BaseResourceLocation, - default=ResourceLocation, -) +_T_ResourceLocation = TypeVar("_T_ResourceLocation", default=ResourceLocation) class HexdocImage(TemplateModel, Generic[_T_ResourceLocation], ABC): @@ -49,10 +40,10 @@ class HexdocImage(TemplateModel, Generic[_T_ResourceLocation], ABC): def __init_subclass__( cls, *, - template_type: str | ResourceLocation | InheritType | None = Inherit, - **kwargs: Unpack[ConfigDict], + template_id: str | ResourceLocation | InheritType | None = Inherit, + **kwargs: Any, ): - super().__init_subclass__(template_type=template_type, **kwargs) + super().__init_subclass__(template_id=template_id, **kwargs) @classproperty @classmethod @@ -92,8 +83,8 @@ def _get_name(self, info: ValidationInfo): class ItemImage(HexdocImage[ItemStack], InlineItemModel, UnionModel, ABC): @override - @abstractmethod @classmethod + @abstractmethod def load_id(cls, item: ItemStack, context: dict[str, Any]) -> Any: pm = PluginManager.of(context) return cls._resolve_union( diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index 069daecf..e79e4bc1 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -62,6 +62,7 @@ class HexdocAssetLoader: site_url: PydanticURL asset_url: PydanticURL render_dir: Path + default_renderer: ModelRenderer | None = None @cached_property def gaslighting_items(self): @@ -120,7 +121,7 @@ def load_item_models(self) -> Iterable[tuple[ResourceLocation, ModelItem]]: @cached_property def renderer(self): - return ModelRenderer( + return self.default_renderer or ModelRenderer( loader=self.loader, output_dir=self.render_dir, ) diff --git a/src/hexdoc/model/tagged_union.py b/src/hexdoc/model/tagged_union.py index c6569ee6..6469f269 100644 --- a/src/hexdoc/model/tagged_union.py +++ b/src/hexdoc/model/tagged_union.py @@ -392,15 +392,15 @@ class TemplateModel(HexdocModel, ABC): def __init_subclass__( cls, *, - template_type: str | ResourceLocation | InheritType | None = None, + template_id: str | ResourceLocation | InheritType | None = None, **kwargs: Unpack[ConfigDict], ) -> None: super().__init_subclass__(**kwargs) - match template_type: + match template_id: case str(): - cls._template_id = ResourceLocation.from_str(template_type) + cls._template_id = ResourceLocation.from_str(template_id) case ResourceLocation() | None: - cls._template_id = template_type + cls._template_id = template_id case InheritType(): pass @@ -440,6 +440,6 @@ def __init_subclass__( super().__init_subclass__( type=type, # pyright doesn't seem to understand multiple inheritance here - template_type=template_type, # pyright: ignore[reportCallIssue] + template_id=template_type, # pyright: ignore[reportCallIssue] **kwargs, ) diff --git a/test/integration/test_extend_book.py b/test/integration/test_extend_book.py index 6762dd7b..47f11bb5 100644 --- a/test/integration/test_extend_book.py +++ b/test/integration/test_extend_book.py @@ -8,6 +8,8 @@ from hexdoc.core.compat import MinecraftVersion from hexdoc.core.properties import EnvironmentVariableProps, Properties, TexturesProps from hexdoc.core.resource import ResourceLocation +from hexdoc.graphics.loader import ImageLoader +from hexdoc.graphics.renderer import ModelRenderer from hexdoc.minecraft import I18n from hexdoc.patchouli.book import Book from hexdoc.patchouli.book_context import BookContext @@ -150,10 +152,34 @@ def child_loader(child_props: Properties, pm: PluginManager): @pytest.fixture -def parent_book(pm: PluginManager, parent_loader: ModResourceLoader): +def parent_renderer(parent_loader: ModResourceLoader): + with ModelRenderer(loader=parent_loader) as renderer: + yield renderer + + +@pytest.fixture +def child_renderer(child_loader: ModResourceLoader): + with ModelRenderer(loader=child_loader) as renderer: + yield renderer + + +@pytest.fixture +def parent_book( + tmp_path: Path, + pm: PluginManager, + parent_loader: ModResourceLoader, + parent_renderer: ModelRenderer, +): parent_props = parent_loader.props assert parent_props.book_id + image_loader = ImageLoader( + loader=parent_loader, + renderer=parent_renderer, + site_dir=tmp_path, + site_url=URL(), + ) + book_plugin = pm.book_plugin(parent_props.book_type) book_id, book_data = book_plugin.load_book_data(parent_props.book_id, parent_loader) @@ -169,6 +195,7 @@ def parent_book(pm: PluginManager, parent_loader: ModResourceLoader): book_data=book_data, pm=pm, loader=parent_loader, + image_loader=image_loader, i18n=i18n, all_metadata={}, ) @@ -179,10 +206,22 @@ def parent_book(pm: PluginManager, parent_loader: ModResourceLoader): @pytest.fixture -def child_book(pm: PluginManager, child_loader: ModResourceLoader): +def child_book( + tmp_path: Path, + pm: PluginManager, + child_loader: ModResourceLoader, + child_renderer: ModelRenderer, +): child_props = child_loader.props assert child_props.book_id + image_loader = ImageLoader( + loader=child_loader, + renderer=child_renderer, + site_dir=tmp_path, + site_url=URL(), + ) + book_plugin = pm.book_plugin(child_props.book_type) book_id, book_data = book_plugin.load_book_data(child_props.book_id, child_loader) @@ -198,6 +237,7 @@ def child_book(pm: PluginManager, child_loader: ModResourceLoader): book_data=book_data, pm=pm, loader=child_loader, + image_loader=image_loader, i18n=i18n, all_metadata={}, ) diff --git a/test/integration/test_modpack.py b/test/integration/test_modpack.py index ef3779bb..a2bdff8f 100644 --- a/test/integration/test_modpack.py +++ b/test/integration/test_modpack.py @@ -8,11 +8,14 @@ from hexdoc.core.compat import MinecraftVersion from hexdoc.core.properties import Properties from hexdoc.core.resource import ResourceLocation +from hexdoc.graphics.loader import ImageLoader +from hexdoc.graphics.renderer import ModelRenderer from hexdoc.minecraft import I18n from hexdoc.patchouli.book import Book from hexdoc.patchouli.text import FormatTree from hexdoc.plugin import PluginManager from pytest import MonkeyPatch +from yarl import URL from ..tree import write_file_tree @@ -83,10 +86,28 @@ def loader(props: Properties, pm: PluginManager): @pytest.fixture -def book_and_context(pm: PluginManager, loader: ModResourceLoader): +def renderer(loader: ModResourceLoader): + with ModelRenderer(loader=loader) as renderer: + yield renderer + + +@pytest.fixture +def book_and_context( + tmp_path: Path, + pm: PluginManager, + loader: ModResourceLoader, + renderer: ModelRenderer, +): props = loader.props assert props.book_id + image_loader = ImageLoader( + loader=loader, + renderer=renderer, + site_dir=tmp_path, + site_url=URL(), + ) + book_plugin = pm.book_plugin(props.book_type) book_id, book_data = book_plugin.load_book_data(props.book_id, loader) @@ -102,6 +123,7 @@ def book_and_context(pm: PluginManager, loader: ModResourceLoader): book_data=book_data, pm=pm, loader=loader, + image_loader=image_loader, i18n=i18n, all_metadata={}, ) From 114ce71d5ffaa1aef6b1e7cb9140a49ce0cb000c Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 20:51:46 -0400 Subject: [PATCH 048/106] Fix import error --- src/hexdoc/minecraft/assets/load_assets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index e79e4bc1..9190fcf7 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -18,8 +18,9 @@ from hexdoc.utils import PydanticURL from hexdoc.utils.context import ContextSource +from ..model.animation import AnimationMeta from ..tags import Tag -from .animated import AnimatedTexture, AnimationMeta +from .animated import AnimatedTexture from .constants import MISSING_TEXTURE_URL from .items import ( ImageTexture, From c281e4ea32283ab4cc80c6f244de56c80224edb9 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 20:55:32 -0400 Subject: [PATCH 049/106] Fix URL constructor error --- src/hexdoc/cli/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 59713160..e318787c 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -220,7 +220,7 @@ def build( loader=loader, renderer=renderer, site_dir=site_dir, - site_url=URL(*site_path.parts), + site_url=URL().joinpath(*site_path.parts), ) all_metadata = render_textures_and_export_metadata(loader, asset_loader) From 95855950e7740ac0b1e7b5e922d5283b6aea82a9 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 21:04:49 -0400 Subject: [PATCH 050/106] Fix images being written to the wrong location --- src/hexdoc/cli/app.py | 1 - src/hexdoc/minecraft/assets/load_assets.py | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index e318787c..5880a8c2 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -214,7 +214,6 @@ def build( asset_url=props.env.asset_url, render_dir=site_dir, ) - asset_loader.default_renderer = renderer image_loader = ImageLoader( loader=loader, diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index 9190fcf7..9902b2c2 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -63,7 +63,6 @@ class HexdocAssetLoader: site_url: PydanticURL asset_url: PydanticURL render_dir: Path - default_renderer: ModelRenderer | None = None @cached_property def gaslighting_items(self): @@ -122,7 +121,7 @@ def load_item_models(self) -> Iterable[tuple[ResourceLocation, ModelItem]]: @cached_property def renderer(self): - return self.default_renderer or ModelRenderer( + return ModelRenderer( loader=self.loader, output_dir=self.render_dir, ) From 8767da68ae380a0aff54e6083c414bf94dadbf94 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 21:34:22 -0400 Subject: [PATCH 051/106] Only catch validation-related exceptions when resolving unions --- src/hexdoc/model/tagged_union.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hexdoc/model/tagged_union.py b/src/hexdoc/model/tagged_union.py index 6469f269..f6ebca40 100644 --- a/src/hexdoc/model/tagged_union.py +++ b/src/hexdoc/model/tagged_union.py @@ -73,7 +73,7 @@ def _resolve_union( ) if allow_ambiguous: return result - except Exception as e: + except (ValueError, AssertionError, ValidationError) as e: exceptions.append( InitErrorDetails( type=PydanticCustomError( From 49e16ed67766c8fd7dbe517b850f23afb3e80320 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 21:35:25 -0400 Subject: [PATCH 052/106] Make hexdoc.cli.utils.init_context a contextmanager to set context for HexdocModel.__init__ --- src/hexdoc/cli/app.py | 12 ++++++------ src/hexdoc/cli/utils/load.py | 8 +++++++- test/integration/test_extend_book.py | 20 ++++++++------------ test/integration/test_modpack.py | 10 ++++------ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 5880a8c2..fa1eabd5 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -152,7 +152,7 @@ def repl(*, props_file: PropsOption): ) if book_id and book_data: - context = init_context( + with init_context( book_id=book_id, book_data=book_data, pm=pm, @@ -160,8 +160,8 @@ def repl(*, props_file: PropsOption): image_loader=image_loader, i18n=i18n, all_metadata=all_metadata, - ) - book = book_plugin.validate_book(book_data, context=context) + ) as context: + book = book_plugin.validate_book(book_data, context=context) repl_locals |= dict( book=book, context=context, @@ -239,7 +239,7 @@ def build( books = list[LoadedBookInfo]() for language, i18n in all_i18n.items(): try: - context = init_context( + with init_context( book_id=book_id, book_data=book_data, pm=pm, @@ -247,8 +247,8 @@ def build( image_loader=image_loader, i18n=i18n, all_metadata=all_metadata, - ) - book = book_plugin.validate_book(book_data, context=context) + ) as context: + book = book_plugin.validate_book(book_data, context=context) books.append( LoadedBookInfo( language=language, diff --git a/src/hexdoc/cli/utils/load.py b/src/hexdoc/cli/utils/load.py index 69fd35bd..3ee1ae3c 100644 --- a/src/hexdoc/cli/utils/load.py +++ b/src/hexdoc/cli/utils/load.py @@ -1,4 +1,5 @@ import logging +from contextlib import contextmanager from pathlib import Path from textwrap import indent from typing import Any, Literal, overload @@ -23,6 +24,7 @@ TextureContext, TextureLookups, ) +from hexdoc.model import init_context as set_init_context from hexdoc.patchouli import BookContext from hexdoc.patchouli.text import DEFAULT_MACROS, FormattingContext from hexdoc.plugin import BookPlugin, ModPlugin, ModPluginWithBook, PluginManager @@ -118,6 +120,7 @@ def render_textures_and_export_metadata( # TODO: refactor a lot of this out +@contextmanager def init_context( *, book_id: ResourceLocation, @@ -128,6 +131,8 @@ def init_context( i18n: I18n, all_metadata: dict[str, HexdocMetadata], ): + """This is only a contextmanager so it can call `hexdoc.model.init_context`.""" + props = loader.props context = dict[str, Any]() @@ -160,4 +165,5 @@ def init_context( for item in pm.update_context(context): item.add_to_context(context) - return context + with set_init_context(context): + yield context diff --git a/test/integration/test_extend_book.py b/test/integration/test_extend_book.py index 47f11bb5..b2dc63c8 100644 --- a/test/integration/test_extend_book.py +++ b/test/integration/test_extend_book.py @@ -190,7 +190,7 @@ def parent_book( lang=parent_props.default_lang, ) - context = init_context( + with init_context( book_id=book_id, book_data=book_data, pm=pm, @@ -198,11 +198,9 @@ def parent_book( image_loader=image_loader, i18n=i18n, all_metadata={}, - ) - - book = book_plugin.validate_book(book_data, context=context) - - return book, context + ) as context: + book = book_plugin.validate_book(book_data, context=context) + yield book, context @pytest.fixture @@ -232,7 +230,7 @@ def child_book( lang=child_props.default_lang, ) - context = init_context( + with init_context( book_id=book_id, book_data=book_data, pm=pm, @@ -240,11 +238,9 @@ def child_book( image_loader=image_loader, i18n=i18n, all_metadata={}, - ) - - book = book_plugin.validate_book(book_data, context=context) - - return book, context + ) as context: + book = book_plugin.validate_book(book_data, context=context) + yield book, context def test_parent_ids(parent_book: tuple[Book, dict[str, Any]]): diff --git a/test/integration/test_modpack.py b/test/integration/test_modpack.py index a2bdff8f..60c4a53d 100644 --- a/test/integration/test_modpack.py +++ b/test/integration/test_modpack.py @@ -118,7 +118,7 @@ def book_and_context( lang=props.default_lang, ) - context = init_context( + with init_context( book_id=book_id, book_data=book_data, pm=pm, @@ -126,11 +126,9 @@ def book_and_context( image_loader=image_loader, i18n=i18n, all_metadata={}, - ) - - book = book_plugin.validate_book(book_data, context=context) - - yield book, context + ) as context: + book = book_plugin.validate_book(book_data, context=context) + yield book, context def test_book_name(book_and_context: tuple[Book, dict[str, Any]]): From 0c6888baf0cd4c547edeb0e6d985ef069728740b Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 21:48:06 -0400 Subject: [PATCH 053/106] Fix _from_renderer cache hit behaviour --- src/hexdoc/graphics/loader.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index 51d4dbda..627574e7 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -106,7 +106,7 @@ def _get_overrides(self, model_id: ResourceLocation): # TODO: implement (maybe) yield model_id - def _load_model(self, model_id: ResourceLocation): + def _load_model(self, model_id: ResourceLocation) -> LoadedModel | BlockModel: if result := self._model_cache.get(model_id): logger.debug(f"Cache hit: {model_id} = {result}") return result @@ -115,7 +115,7 @@ def _load_model(self, model_id: ResourceLocation): _, model = BlockModel.load_and_resolve(self.loader, model_id) return model except Exception as e: - return self._fail(f"Failed to load model: {model_id}: {e}") + return self._fail(f"Failed to load model: {model_id}: {e}"), None def _render_existing_texture(self, src: Path, output_id: ResourceLocation): fragment = self._get_fragment(output_id, src.suffix) @@ -192,7 +192,7 @@ def inner(model_id: ResourceLocation): def _from_renderer(self, model_id: ResourceLocation): model = self._load_model(model_id) if not isinstance(model, BlockModel): - return None + return model fragment = self._get_fragment(model_id) suffix = self.renderer.render_model(model, self.site_dir / fragment) return self._fragment_to_url(fragment.with_suffix(suffix)), model From 08877444475c5af860ff1160ef8f50313618f872 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 22:38:38 -0400 Subject: [PATCH 054/106] Set textures.strict=false for dummy book --- noxfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/noxfile.py b/noxfile.py index dc6ca088..3ae276ba 100644 --- a/noxfile.py +++ b/noxfile.py @@ -497,6 +497,9 @@ def dummy_setup(session: nox.Session): ] export_dir = "src/hexdoc_dummy/_export/generated" + [textures] + strict = false + [template] icon = "icon.png" include = [ From 74eb04fefed13d95fc50d540378aadf8bed7d147 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 22:41:35 -0400 Subject: [PATCH 055/106] Fix moderngl context error caused by creating multiple BlockRenderer instances --- src/hexdoc/cli/app.py | 1 + src/hexdoc/graphics/renderer.py | 7 +++---- src/hexdoc/minecraft/assets/load_assets.py | 22 ++++++++++++---------- 3 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index fa1eabd5..2d4cb26b 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -214,6 +214,7 @@ def build( asset_url=props.env.asset_url, render_dir=site_dir, ) + asset_loader.renderer = renderer image_loader = ImageLoader( loader=loader, diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index abfd8e50..a5b51f4f 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -26,8 +26,10 @@ @dataclass(kw_only=True) class ModelRenderer: + """Avoid creating multiple instances of this class - it seems to cause issues with + the OpenGL/ModernGL context.""" + loader: ModResourceLoader - output_dir: Path | None = None debug: DebugType = DebugType.NONE block_size: int | None = None item_size: int | None = None @@ -74,9 +76,6 @@ def render_model( def save_image(self, output_path: str | Path, frames: list[Image.Image]): output_path = Path(output_path) - if self.output_dir and not output_path.is_absolute(): - output_path = self.output_dir / output_path - output_path.parent.mkdir(parents=True, exist_ok=True) match frames: diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index 9902b2c2..bb72e954 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -1,7 +1,7 @@ import logging import textwrap from collections.abc import Set -from dataclasses import dataclass +from dataclasses import dataclass, field from functools import cached_property from pathlib import Path from typing import Any, Iterable, Iterator, TypeVar, cast @@ -64,6 +64,9 @@ class HexdocAssetLoader: asset_url: PydanticURL render_dir: Path + # FIXME: so so so awfully hacky. i hate it here + renderer: ModelRenderer = field(init=False) + @cached_property def gaslighting_items(self): return Tag.GASLIGHTING_ITEMS.load(self.loader).value_ids_set @@ -119,13 +122,6 @@ def load_item_models(self) -> Iterable[tuple[ResourceLocation, ModelItem]]: model = ModelItem.load_data("item" / item_id, data) yield item_id, model - @cached_property - def renderer(self): - return ModelRenderer( - loader=self.loader, - output_dir=self.render_dir, - ) - def fallback_texture(self, item_id: ResourceLocation) -> ItemTexture | None: return None @@ -175,6 +171,7 @@ def load_and_render_internal_textures( self.gaslighting_items, image_textures, self.site_url, + self.render_dir, ): found_items_from_models.add(item_id) yield item_id, result @@ -242,6 +239,7 @@ def load_and_render_item( gaslighting_items: Set[ResourceLocation], image_textures: dict[ResourceLocation, ImageTexture], site_url: URL, + output_dir: Path, ) -> ItemTexture | None: try: match model.find_texture(loader, gaslighting_items): @@ -255,6 +253,7 @@ def load_and_render_item( renderer, image_textures, site_url, + output_dir, ).inner for found_texture in found_textures ) @@ -266,6 +265,7 @@ def load_and_render_item( renderer, image_textures, site_url, + output_dir, ) return texture except TextureNotFoundError as e: @@ -279,6 +279,7 @@ def lookup_or_render_single_item( renderer: ModelRenderer, image_textures: dict[ResourceLocation, ImageTexture], site_url: URL, + output_dir: Path, ) -> SingleItemTexture: match found_texture: case "texture", texture_id: @@ -287,13 +288,14 @@ def lookup_or_render_single_item( return SingleItemTexture(inner=image_textures[texture_id]) case "block_model", model_id: - return render_block(model_id, renderer, site_url) + return render_block(model_id, renderer, site_url, output_dir) def render_block( id: ResourceLocation, renderer: ModelRenderer, site_url: URL, + output_dir: Path, ) -> SingleItemTexture: # FIXME: hack id_out_path = id.path @@ -306,7 +308,7 @@ def render_block( try: # FIXME: scuffed - suffix = renderer.render_model(id, out_path) + suffix = renderer.render_model(id, output_dir / out_path) out_path = out_path.removesuffix(".png") + suffix except Exception as e: if renderer.loader.props.textures.strict: From df0a82dfb1cfaecdeb1a3b7db1eb98cd9807ca59 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 22:42:45 -0400 Subject: [PATCH 056/106] Implement image templates, return item type from ImageLoader to get pixelated value --- .../images/hexdoc/cycling.html.jinja | 19 +++++++++++++ .../images/hexdoc/single.html.jinja | 13 +++++++++ .../_templates/macros/images.html.jinja | 12 ++++++++ src/hexdoc/graphics/loader.py | 28 +++++++++++++------ src/hexdoc/graphics/renderer.py | 20 ++++++++++++- src/hexdoc/graphics/validators.py | 9 ++++-- src/hexdoc/minecraft/assets/load_assets.py | 2 +- 7 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 src/hexdoc/_templates/images/hexdoc/cycling.html.jinja create mode 100644 src/hexdoc/_templates/images/hexdoc/single.html.jinja create mode 100644 src/hexdoc/_templates/macros/images.html.jinja diff --git a/src/hexdoc/_templates/images/hexdoc/cycling.html.jinja b/src/hexdoc/_templates/images/hexdoc/cycling.html.jinja new file mode 100644 index 00000000..d0d7b03a --- /dev/null +++ b/src/hexdoc/_templates/images/hexdoc/cycling.html.jinja @@ -0,0 +1,19 @@ +{% import "macros/images.html.jinja" as Images with context -%} + +
+ {% for child in image.images %} + {{ + Images.image( + child, + class_names=class_names, + is_first=loop.first, + ) + }} + {% endfor %} +
diff --git a/src/hexdoc/_templates/images/hexdoc/single.html.jinja b/src/hexdoc/_templates/images/hexdoc/single.html.jinja new file mode 100644 index 00000000..08d8deb7 --- /dev/null +++ b/src/hexdoc/_templates/images/hexdoc/single.html.jinja @@ -0,0 +1,13 @@ +{{ name }} diff --git a/src/hexdoc/_templates/macros/images.html.jinja b/src/hexdoc/_templates/macros/images.html.jinja new file mode 100644 index 00000000..12791979 --- /dev/null +++ b/src/hexdoc/_templates/macros/images.html.jinja @@ -0,0 +1,12 @@ +{% macro image(image, name=none, class_names=[], lazy=true, title=true, is_first=none) -%} + {% with name = name if name is not none else image.name %} + {% include image.template~".html.jinja" %} + {% endwith %} +{%- endmacro %} + +{% macro item(item, is_first=none, count=1) -%} + {{ image(item, is_first=is_first, class_names=["item-texture"]) }} + {% if count > 1 -%} +
{{ count }}
+ {%- endif %} +{%- endmacro %} diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index 627574e7..20234d02 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -10,7 +10,7 @@ from hexdoc.minecraft.model import BlockModel from hexdoc.utils import ValidationContext -from .renderer import ModelRenderer +from .renderer import ImageType, ModelRenderer from .texture import ModelTexture logger = logging.getLogger(__name__) @@ -18,7 +18,13 @@ MISSING_TEXTURE_ID = ResourceLocation("hexdoc", "textures/item/missing.png") TAG_TEXTURE_ID = ResourceLocation("hexdoc", "textures/item/tag.png") -LoadedModel = tuple[URL, BlockModel | None] + +@dataclass +class LoadedModel: + url: URL + model: BlockModel | None = None + image_type: ImageType = ImageType.UNKNOWN + ModelLoaderStrategy = Callable[[ResourceLocation], LoadedModel | None] @@ -72,7 +78,7 @@ def render_model(self, model_id: BaseResourceLocation) -> LoadedModel: exc_info=True, ) - return self._fail(f"Failed to render model: {model_id}"), None + return LoadedModel(self._fail(f"Failed to render model: {model_id}")) def render_texture(self, texture_id: ResourceLocation) -> URL: if result := self._texture_cache.get(texture_id): @@ -115,7 +121,7 @@ def _load_model(self, model_id: ResourceLocation) -> LoadedModel | BlockModel: _, model = BlockModel.load_and_resolve(self.loader, model_id) return model except Exception as e: - return self._fail(f"Failed to load model: {model_id}: {e}"), None + return LoadedModel(self._fail(f"Failed to load model: {model_id}: {e}")) def _render_existing_texture(self, src: Path, output_id: ResourceLocation): fragment = self._get_fragment(output_id, src.suffix) @@ -167,9 +173,9 @@ def _from_props(self, model_id: ResourceLocation): match self.props.textures.overrides.models.get(model_id): case ResourceLocation() as texture_id: _, src = self.loader.find_resource("assets", "", texture_id) - return self._render_existing_texture(src, model_id), None + return LoadedModel(self._render_existing_texture(src, model_id)) case URL() as url: - return url, None + return LoadedModel(url) case None: logger.debug(f"No props override for model: {model_id}") return None @@ -183,7 +189,7 @@ def inner(model_id: ResourceLocation): folder="hexdoc/renders", internal=internal, ): - return self._render_existing_texture(path, model_id), None + return LoadedModel(self._render_existing_texture(path, model_id)) logger.debug(f"No {type_} rendered resource for model: {model_id}") inner.__name__ = f"_from_resources({internal=})" @@ -194,5 +200,9 @@ def _from_renderer(self, model_id: ResourceLocation): if not isinstance(model, BlockModel): return model fragment = self._get_fragment(model_id) - suffix = self.renderer.render_model(model, self.site_dir / fragment) - return self._fragment_to_url(fragment.with_suffix(suffix)), model + suffix, image_type = self.renderer.render_model(model, self.site_dir / fragment) + return LoadedModel( + self._fragment_to_url(fragment.with_suffix(suffix)), + model, + image_type, + ) diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index a5b51f4f..252f1da1 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -4,6 +4,7 @@ import logging from dataclasses import dataclass +from enum import Enum, auto from pathlib import Path from typing import Any @@ -24,6 +25,21 @@ logger = logging.getLogger(__name__) +# FIXME: I don't really like this - ideally we should check the image size and pixelate if it's small +class ImageType(Enum): + BLOCK = auto() + ITEM = auto() + UNKNOWN = auto() + + @property + def pixelated(self): + match self: + case ImageType.BLOCK: + return False + case ImageType.ITEM | ImageType.UNKNOWN: + return True + + @dataclass(kw_only=True) class ModelRenderer: """Avoid creating multiple instances of this class - it seems to cause issues with @@ -69,10 +85,12 @@ def render_model( if model.is_generated_item: frames = self._render_item(model) + image_type = ImageType.ITEM else: frames = self._render_block(model) + image_type = ImageType.BLOCK - return self.save_image(output_path, frames) + return self.save_image(output_path, frames), image_type def save_image(self, output_path: str | Path, frames: list[Image.Image]): output_path = Path(output_path) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 76d4534f..d01b05c7 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -101,8 +101,13 @@ class SingleItemImage(URLImage[ItemStack], ItemImage): @override @classmethod def load_id(cls, item: ItemStack, context: dict[str, Any]) -> Any: - url, model = ImageLoader.of(context).render_item(item) - return cls(id=item, url=url, model=model) + result = ImageLoader.of(context).render_item(item) + return cls( + id=item, + url=result.url, + model=result.model, + pixelated=result.image_type.pixelated, + ) @override def _get_name(self, info: ValidationInfo): diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py index bb72e954..891f40bf 100644 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ b/src/hexdoc/minecraft/assets/load_assets.py @@ -308,7 +308,7 @@ def render_block( try: # FIXME: scuffed - suffix = renderer.render_model(id, output_dir / out_path) + suffix, _ = renderer.render_model(id, output_dir / out_path) out_path = out_path.removesuffix(".png") + suffix except Exception as e: if renderer.loader.props.textures.strict: From 638fa0d2717b026a8c58ca77158518f254e208f0 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 22 May 2024 23:07:43 -0400 Subject: [PATCH 057/106] Explicitly export all blockstates/models/textures --- src/hexdoc/cli/app.py | 11 +++++++++++ src/hexdoc/core/loader.py | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 2d4cb26b..f5a1b5fb 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -225,6 +225,17 @@ def build( all_metadata = render_textures_and_export_metadata(loader, asset_loader) + # FIXME: put this somewhere saner? + logger.info("Exporting all image-related resources.") + for folder in ["blockstates", "models", "textures"]: + loader.export_resources( + "assets", + namespace="*", + folder=folder, + glob="**/*.*", + allow_missing=True, + ) + if not props.book_id: logger.info("Skipping book load because props.book_id is not set.") return site_dir diff --git a/src/hexdoc/core/loader.py b/src/hexdoc/core/loader.py index f1ed0487..011a8f8e 100644 --- a/src/hexdoc/core/loader.py +++ b/src/hexdoc/core/loader.py @@ -468,15 +468,46 @@ def _load_path( return value + def export_resources( + self, + type: ResourceType, + *, + namespace: str, + folder: str | Path, + glob: str | list[str] = "**/*", + allow_missing: bool = False, + internal_only: bool = False, + ): + for resource_dir, _, path in self.find_resources( + type, + namespace=namespace, + folder=folder, + glob=glob, + allow_missing=allow_missing, + internal_only=internal_only, + ): + if resource_dir.reexport: + self.export( + path=path.relative_to(resource_dir.path), + data=path.read_bytes(), + ) + @overload - def export(self, /, path: Path, data: str, *, cache: bool = False) -> None: ... + def export( + self, + /, + path: Path, + data: str | bytes, + *, + cache: bool = False, + ) -> None: ... @overload def export( self, /, path: Path, - data: str, + data: str | bytes, value: _T, *, decode: Callable[[str], _T] = decode_json_dict, @@ -487,7 +518,7 @@ def export( def export( self, path: Path, - data: str, + data: str | bytes, value: _T = None, *, decode: Callable[[str], _T] = decode_json_dict, From d7a03010ae956908012bb02300c2dba89b492ec5 Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 23 May 2024 01:30:21 -0400 Subject: [PATCH 058/106] Add better error message if validate_texture gets a value without a slash --- src/hexdoc/minecraft/i18n.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hexdoc/minecraft/i18n.py b/src/hexdoc/minecraft/i18n.py index d868022e..f8aafa73 100644 --- a/src/hexdoc/minecraft/i18n.py +++ b/src/hexdoc/minecraft/i18n.py @@ -349,6 +349,11 @@ def fallback_tag_name(self, tag: ResourceLocation): def localize_texture(self, texture_id: ResourceLocation, silent: bool = False): path = texture_id.path.removeprefix("textures/").removesuffix(".png") + if "/" not in path: + raise ValueError( + f"Unable to localize texture id not containing '/': {texture_id}" + ) + root, rest = path.split("/", 1) # TODO: refactor / extensibilify From 3a6f39401a3bb8ec7f0f6ff100664b381daa669a Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 23 May 2024 01:31:52 -0400 Subject: [PATCH 059/106] Add ImageField annotation to properly/consistently handle missing textures --- src/hexdoc/_hooks.py | 4 +-- src/hexdoc/graphics/__init__.py | 5 ++- src/hexdoc/graphics/annotations.py | 54 ++++++++++++++++++++++++++++++ src/hexdoc/graphics/loader.py | 22 ++---------- src/hexdoc/graphics/validators.py | 31 +++++++++++++++-- 5 files changed, 91 insertions(+), 25 deletions(-) create mode 100644 src/hexdoc/graphics/annotations.py diff --git a/src/hexdoc/_hooks.py b/src/hexdoc/_hooks.py index e4c0042d..875e80b0 100644 --- a/src/hexdoc/_hooks.py +++ b/src/hexdoc/_hooks.py @@ -9,7 +9,7 @@ import hexdoc from hexdoc import HEXDOC_MODID, VERSION from hexdoc.core import IsVersion, ModResourceLoader, ResourceLocation -from hexdoc.graphics.validators import SingleItemImage +from hexdoc.graphics.validators import ItemImage, SingleItemImage from hexdoc.minecraft.recipe import ( ingredients as minecraft_ingredients, recipes as minecraft_recipes, @@ -131,7 +131,7 @@ def default_rendered_templates_v2( return templates - def item_image_types(self): + def item_image_types(self) -> HookReturn[type[ItemImage]]: return SingleItemImage diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index e0e9f759..bd8b4403 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -1,15 +1,18 @@ __all__ = [ "DebugType", + "ImageField", "ImageLoader", "ItemImage", + "MissingImage", "ModelRenderer", "ModelTexture", "TagImage", "TextureImage", ] +from .annotations import ImageField, ItemImage, TagImage, TextureImage from .loader import ImageLoader from .renderer import ModelRenderer from .texture import ModelTexture from .utils import DebugType -from .validators import ItemImage, TagImage, TextureImage +from .validators import MissingImage diff --git a/src/hexdoc/graphics/annotations.py b/src/hexdoc/graphics/annotations.py new file mode 100644 index 00000000..29e81ed9 --- /dev/null +++ b/src/hexdoc/graphics/annotations.py @@ -0,0 +1,54 @@ +from contextvars import ContextVar +from typing import Annotated, Any, TypeVar + +from pydantic import BeforeValidator, ValidationError, ValidationInfo, WrapValidator +from pydantic.functional_validators import ModelWrapValidatorHandler + +from hexdoc.utils.contextmanagers import set_contextvar + +from .validators import ( + HexdocImage, + ItemImage as ItemImageType, + MissingImage, + TagImage as TagImageType, + TextureImage as TextureImageType, +) + +_T_HexdocImage = TypeVar("_T_HexdocImage", bound=HexdocImage[Any]) + +_is_annotated_contextvar = ContextVar("_is_annotated_contextvar", default=False) + + +def _validate_image_field( + value: Any, + handler: ModelWrapValidatorHandler[Any], + info: ValidationInfo, +): + try: + with set_contextvar(_is_annotated_contextvar, True): + return handler(value) + except ValidationError: + missing = MissingImage.model_validate(value, context=info.context) + return missing + + +def _assert_annotated(model_type: type[_T_HexdocImage]): + def validator(value: Any, info: ValidationInfo): + if not _is_annotated_contextvar.get(): + field_name = f" (field: {info.field_name})" if info.field_name else "" + raise RuntimeError( + f"{model_type.__name__}{field_name} must be wrapped with ImageField" + ) + return value + + return BeforeValidator(validator) + + +ImageField = Annotated[ + _T_HexdocImage | MissingImage, + WrapValidator(_validate_image_field), +] + +ItemImage = Annotated[ItemImageType, _assert_annotated(ItemImageType)] +TagImage = Annotated[TagImageType, _assert_annotated(TagImageType)] +TextureImage = Annotated[TextureImageType, _assert_annotated(TextureImageType)] diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index 20234d02..38f65c7c 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -78,7 +78,7 @@ def render_model(self, model_id: BaseResourceLocation) -> LoadedModel: exc_info=True, ) - return LoadedModel(self._fail(f"Failed to render model: {model_id}")) + raise ValueError(f"Failed to render model: {model_id}") def render_texture(self, texture_id: ResourceLocation) -> URL: if result := self._texture_cache.get(texture_id): @@ -90,23 +90,7 @@ def render_texture(self, texture_id: ResourceLocation) -> URL: self._texture_cache[texture_id] = result return result except FileNotFoundError: - # prevent infinite recursion if something really weird happens - # use RuntimeError instead of assert so Pydantic doesn't catch it - if texture_id == MISSING_TEXTURE_ID: - raise RuntimeError( - f"Built-in missing texture {MISSING_TEXTURE_ID} not found" - + " (this should never happen)" - ) - - return self._fail(f"Failed to find texture: {texture_id}") - - def _fail(self, message: str): - if self.props.textures.strict: - raise ValueError(message) - logger.error(message) - missing = self.render_texture(MISSING_TEXTURE_ID) - assert missing is not None - return missing + raise ValueError(f"Failed to find texture: {texture_id}") def _get_overrides(self, model_id: ResourceLocation): # TODO: implement (maybe) @@ -121,7 +105,7 @@ def _load_model(self, model_id: ResourceLocation) -> LoadedModel | BlockModel: _, model = BlockModel.load_and_resolve(self.loader, model_id) return model except Exception as e: - return LoadedModel(self._fail(f"Failed to load model: {model_id}: {e}")) + raise ValueError(f"Failed to load model: {model_id}: {e}") from e def _render_existing_texture(self, src: Path, output_id: ResourceLocation): fragment = self._get_fragment(output_id, src.suffix) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index d01b05c7..f5a6642d 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -1,18 +1,20 @@ from __future__ import annotations +import logging from abc import ABC, abstractmethod from typing import Any, Generic from pydantic import ( Field, PrivateAttr, + ValidationError, ValidationInfo, field_validator, model_validator, ) from typing_extensions import TypeVar, override -from hexdoc.core import ItemStack, ResourceLocation +from hexdoc.core import ItemStack, Properties, ResourceLocation from hexdoc.minecraft.i18n import I18n, LocalizedStr from hexdoc.minecraft.model import BlockModel from hexdoc.model import ( @@ -24,7 +26,9 @@ from hexdoc.plugin import PluginManager from hexdoc.utils import Inherit, InheritType, PydanticURL, classproperty -from .loader import TAG_TEXTURE_ID, ImageLoader +from .loader import MISSING_TEXTURE_ID, TAG_TEXTURE_ID, ImageLoader + +logger = logging.getLogger(__name__) _T_ResourceLocation = TypeVar("_T_ResourceLocation", default=ResourceLocation) @@ -60,7 +64,11 @@ def _get_name(self, info: ValidationInfo) -> LocalizedStr: ... @model_validator(mode="after") def _set_name(self, info: ValidationInfo): - self._name = self._get_name(info) + try: + self._name = self._get_name(info) + except ValidationError as e: + logger.debug(f"Failed to get name for {self.__class__}: {e}") + self._name = LocalizedStr.with_value(str(self.id)) return self @@ -81,6 +89,23 @@ def _get_name(self, info: ValidationInfo): return I18n.of(info).localize_texture(self.id) +class MissingImage(TextureImage): + @override + @classmethod + def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: + message = f"Using missing texture for id: {id}" + if Properties.of(context).textures.strict: + raise ValueError(message) + logger.warning(message) + + url = ImageLoader.of(context).render_texture(MISSING_TEXTURE_ID) + return cls(id=id, url=url, pixelated=True) + + @override + def _get_name(self, info: ValidationInfo): + return LocalizedStr.with_value(str(self.id)) + + class ItemImage(HexdocImage[ItemStack], InlineItemModel, UnionModel, ABC): @override @classmethod From 2fab8f6ceb4e94817071df74998062bce018eb34 Mon Sep 17 00:00:00 2001 From: object-Object Date: Thu, 23 May 2024 01:46:48 -0400 Subject: [PATCH 060/106] Add first_url property to HexdocImage --- src/hexdoc/graphics/validators.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index f5a6642d..69ee336f 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -13,6 +13,7 @@ model_validator, ) from typing_extensions import TypeVar, override +from yarl import URL from hexdoc.core import ItemStack, Properties, ResourceLocation from hexdoc.minecraft.i18n import I18n, LocalizedStr @@ -59,6 +60,10 @@ def template(cls): def name(self): return self._name + @property + @abstractmethod + def first_url(self) -> URL: ... + @abstractmethod def _get_name(self, info: ValidationInfo) -> LocalizedStr: ... @@ -76,6 +81,11 @@ class URLImage(HexdocImage[_T_ResourceLocation], template_id="hexdoc:single"): url: PydanticURL pixelated: bool = True + @property + @override + def first_url(self): + return self.url + class TextureImage(URLImage[ResourceLocation], InlineModel): @override @@ -142,6 +152,11 @@ def _get_name(self, info: ValidationInfo): class CyclingImage(HexdocImage[_T_ResourceLocation], template_id="hexdoc:cycling"): images: list[HexdocImage] = Field(min_length=1) + @property + @override + def first_url(self): + return self.images[0].first_url + @override def _get_name(self, info: ValidationInfo): return self.images[0].name From 326ff5b817f0d52712ceb4e9cfdc43fce9b48554 Mon Sep 17 00:00:00 2001 From: object-Object Date: Fri, 24 May 2024 11:14:55 -0400 Subject: [PATCH 061/106] Implement __hexdoc_check_model_field__ and MustBeAnnotated --- src/hexdoc/graphics/__init__.py | 3 +- src/hexdoc/graphics/annotations.py | 54 ------------------ src/hexdoc/graphics/validators.py | 46 +++++++++++++-- src/hexdoc/model/__init__.py | 3 +- src/hexdoc/model/base.py | 89 +++++++++++++++++++++++++++++- src/hexdoc/model/types.py | 51 ++++++++++++++++- 6 files changed, 182 insertions(+), 64 deletions(-) delete mode 100644 src/hexdoc/graphics/annotations.py diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index bd8b4403..5c287b1d 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -10,9 +10,8 @@ "TextureImage", ] -from .annotations import ImageField, ItemImage, TagImage, TextureImage from .loader import ImageLoader from .renderer import ModelRenderer from .texture import ModelTexture from .utils import DebugType -from .validators import MissingImage +from .validators import ImageField, ItemImage, MissingImage, TagImage, TextureImage diff --git a/src/hexdoc/graphics/annotations.py b/src/hexdoc/graphics/annotations.py deleted file mode 100644 index 29e81ed9..00000000 --- a/src/hexdoc/graphics/annotations.py +++ /dev/null @@ -1,54 +0,0 @@ -from contextvars import ContextVar -from typing import Annotated, Any, TypeVar - -from pydantic import BeforeValidator, ValidationError, ValidationInfo, WrapValidator -from pydantic.functional_validators import ModelWrapValidatorHandler - -from hexdoc.utils.contextmanagers import set_contextvar - -from .validators import ( - HexdocImage, - ItemImage as ItemImageType, - MissingImage, - TagImage as TagImageType, - TextureImage as TextureImageType, -) - -_T_HexdocImage = TypeVar("_T_HexdocImage", bound=HexdocImage[Any]) - -_is_annotated_contextvar = ContextVar("_is_annotated_contextvar", default=False) - - -def _validate_image_field( - value: Any, - handler: ModelWrapValidatorHandler[Any], - info: ValidationInfo, -): - try: - with set_contextvar(_is_annotated_contextvar, True): - return handler(value) - except ValidationError: - missing = MissingImage.model_validate(value, context=info.context) - return missing - - -def _assert_annotated(model_type: type[_T_HexdocImage]): - def validator(value: Any, info: ValidationInfo): - if not _is_annotated_contextvar.get(): - field_name = f" (field: {info.field_name})" if info.field_name else "" - raise RuntimeError( - f"{model_type.__name__}{field_name} must be wrapped with ImageField" - ) - return value - - return BeforeValidator(validator) - - -ImageField = Annotated[ - _T_HexdocImage | MissingImage, - WrapValidator(_validate_image_field), -] - -ItemImage = Annotated[ItemImageType, _assert_annotated(ItemImageType)] -TagImage = Annotated[TagImageType, _assert_annotated(TagImageType)] -TextureImage = Annotated[TextureImageType, _assert_annotated(TextureImageType)] diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 69ee336f..28d29d2f 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -2,16 +2,19 @@ import logging from abc import ABC, abstractmethod -from typing import Any, Generic +from typing import TYPE_CHECKING, Annotated, Any, Generic from pydantic import ( Field, PrivateAttr, + SkipValidation, ValidationError, ValidationInfo, + WrapValidator, field_validator, model_validator, ) +from pydantic.functional_validators import ModelWrapValidatorHandler from typing_extensions import TypeVar, override from yarl import URL @@ -24,6 +27,7 @@ TemplateModel, UnionModel, ) +from hexdoc.model.types import MustBeAnnotated from hexdoc.plugin import PluginManager from hexdoc.utils import Inherit, InheritType, PydanticURL, classproperty @@ -31,10 +35,44 @@ logger = logging.getLogger(__name__) +_T = TypeVar("_T") + _T_ResourceLocation = TypeVar("_T_ResourceLocation", default=ResourceLocation) -class HexdocImage(TemplateModel, Generic[_T_ResourceLocation], ABC): +class _ImageFieldType: + def __class_getitem__(cls, item: Any) -> Any: + return Annotated[item, WrapValidator(cls._validator), cls] + + @staticmethod + def _validator( + value: Any, + handler: ModelWrapValidatorHandler[Any], + info: ValidationInfo, + ): + try: + return handler(value) + except ValidationError: + return MissingImage.model_validate(value, context=info.context) + + +# scuffed, but Pydantic did it first +# see: pydantic.functional_validators.SkipValidation +if TYPE_CHECKING: + ImageField = Annotated[_T, _ImageFieldType] +else: + + class ImageField(_ImageFieldType): + pass + + +class HexdocImage( + TemplateModel, + MustBeAnnotated, + Generic[_T_ResourceLocation], + ABC, + annotation=ImageField, +): """An image that can be rendered in a hexdoc web book.""" id: _T_ResourceLocation @@ -99,7 +137,7 @@ def _get_name(self, info: ValidationInfo): return I18n.of(info).localize_texture(self.id) -class MissingImage(TextureImage): +class MissingImage(TextureImage, annotation=None): @override @classmethod def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: @@ -150,7 +188,7 @@ def _get_name(self, info: ValidationInfo): class CyclingImage(HexdocImage[_T_ResourceLocation], template_id="hexdoc:cycling"): - images: list[HexdocImage] = Field(min_length=1) + images: SkipValidation[list[HexdocImage]] = Field(min_length=1) @property @override diff --git a/src/hexdoc/model/__init__.py b/src/hexdoc/model/__init__.py index b127847a..f04c2224 100644 --- a/src/hexdoc/model/__init__.py +++ b/src/hexdoc/model/__init__.py @@ -9,6 +9,7 @@ "InlineItemModel", "InlineModel", "InternallyTaggedUnion", + "MustBeAnnotated", "NoValue", "NoValueType", "ResourceModel", @@ -44,4 +45,4 @@ TypeTaggedUnion, UnionModel, ) -from .types import Color +from .types import Color, MustBeAnnotated diff --git a/src/hexdoc/model/base.py b/src/hexdoc/model/base.py index c2269c77..45eed580 100644 --- a/src/hexdoc/model/base.py +++ b/src/hexdoc/model/base.py @@ -1,14 +1,26 @@ from __future__ import annotations +import inspect +import typing from contextvars import ContextVar from typing import ( + Annotated, Any, ClassVar, + Sequence, cast, dataclass_transform, ) -from pydantic import BaseModel, ConfigDict, TypeAdapter, ValidationInfo, model_validator +from pydantic import ( + BaseModel, + ConfigDict, + SkipValidation, + TypeAdapter, + ValidationInfo, + model_validator, +) +from pydantic.fields import FieldInfo from pydantic.functional_validators import ModelBeforeValidator from pydantic_settings import BaseSettings, SettingsConfigDict from yarl import URL @@ -50,6 +62,81 @@ class HexdocModel(BaseModel): __hexdoc_before_validator__: ClassVar[ModelBeforeValidator | None] = None + @classmethod + def __hexdoc_check_model_field__( + cls, + model_type: type[HexdocModel], + field_name: str, + field_info: FieldInfo, + origin_stack: Sequence[Any], + annotation_stack: Sequence[Any], + ) -> None: + """Called when initializing a model of type `model_type` for all places where + `cls` is in a type annotation.""" + + # global model field validation (mostly used for HexdocImage) + @classmethod + def __pydantic_init_subclass__(cls, **kwargs: Any) -> None: + super().__pydantic_init_subclass__(**kwargs) + + for field_name, field_info in cls.model_fields.items(): + cls._hexdoc_check_model_field(field_name, field_info) + + @classmethod + def _hexdoc_check_model_field(cls, field_name: str, field_info: FieldInfo): + if field_type := field_info.rebuild_annotation(): + cls._hexdoc_check_model_field_type( + field_name, field_info, field_type, [], [] + ) + + @classmethod + def _hexdoc_check_model_field_type( + cls, + field_name: str, + field_info: FieldInfo, + field_type: Any, + origin_stack: list[Any], + annotation_stack: list[Any], + ): + # TODO: better way to detect recursive types? + if len(origin_stack) > 25: + return + + if inspect.isclass(field_type) and issubclass(field_type, HexdocModel): + field_type.__hexdoc_check_model_field__( + cls, + field_name, + field_info, + origin_stack, + annotation_stack, + ) + + if origin := typing.get_origin(field_type): + args = typing.get_args(field_type) + + if origin is Annotated: + arg, *annotations = args + args = [arg] + else: + annotations = [] + + if any(isinstance(a, SkipValidation) for a in annotations): + return + + origin_stack.append(origin) + annotation_stack += reversed(annotations) + for arg in args: + cls._hexdoc_check_model_field_type( + field_name, + field_info, + arg, + origin_stack, + annotation_stack, + ) + origin_stack.pop() + if annotations: + del annotation_stack[-len(annotations) :] + def __init__(__pydantic_self__, **data: Any) -> None: # type: ignore __tracebackhide__ = True __pydantic_self__.__pydantic_validator__.validate_python( diff --git a/src/hexdoc/model/types.py b/src/hexdoc/model/types.py index 9eed4dbc..bac99709 100644 --- a/src/hexdoc/model/types.py +++ b/src/hexdoc/model/types.py @@ -1,12 +1,18 @@ +import inspect import string -from typing import Any +import textwrap +from typing import Any, ClassVar, Sequence +from copier import ConfigDict from pydantic import field_validator, model_validator from pydantic.dataclasses import dataclass +from pydantic.fields import FieldInfo +from typing_extensions import Unpack +from hexdoc.utils import Inherit, InheritType from hexdoc.utils.json_schema import inherited, json_schema_extra_config, type_str -from .base import DEFAULT_CONFIG +from .base import DEFAULT_CONFIG, HexdocModel @dataclass( @@ -64,3 +70,44 @@ def _check_value(cls, value: Any) -> str: raise ValueError(f"invalid color code: {value}") return value + + +class MustBeAnnotated(HexdocModel): + _annotation_type: ClassVar[type[Any] | None] + + def __init_subclass__( + cls, + annotation: type[Any] | InheritType | None = Inherit, + **kwargs: Unpack[ConfigDict], + ): + super().__init_subclass__(**kwargs) + if annotation != Inherit: + if annotation and not inspect.isclass(annotation): + raise TypeError( + f"Expected annotation to be a type or None, got {type(annotation)}: {annotation}" + ) + cls._annotation_type = annotation + + @classmethod + def __hexdoc_check_model_field__( + cls, + model_type: type[HexdocModel], + field_name: str, + field_info: FieldInfo, + origin_stack: Sequence[Any], + annotation_stack: Sequence[Any], + ) -> None: + if cls._annotation_type is None: + return + if cls._annotation_type not in annotation_stack: + annotation = cls._annotation_type.__name__ + raise TypeError( + textwrap.dedent( + f"""\ + {cls.__name__} must be annotated with {annotation} (eg. {annotation}[{cls.__name__}]) when used as a validation type hint. + Model: {model_type} + Field: {field_name} + Type: {field_info.rebuild_annotation()} + """.rstrip() + ) + ) From b4c7713930549b1a5d330eebb76adaf6ce231f80 Mon Sep 17 00:00:00 2001 From: object-Object Date: Fri, 24 May 2024 12:15:50 -0400 Subject: [PATCH 062/106] Attempt all model overrides if the base model fails, and show all caught exceptions on model render failure --- src/hexdoc/graphics/loader.py | 87 ++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 21 deletions(-) diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index 38f65c7c..530368a3 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -1,6 +1,7 @@ import logging from dataclasses import dataclass from pathlib import Path +from traceback import TracebackException from typing import Callable from yarl import URL @@ -49,6 +50,9 @@ def __post_init__(self): self._from_resources(internal=False), ] + self._overridden_models = set[ResourceLocation]() + self._exceptions = list[Exception]() + @property def props(self): return self.loader.props @@ -60,23 +64,42 @@ def render_item(self, item_id: BaseResourceLocation) -> LoadedModel: return self.render_model("item" / item_id.id) def render_model(self, model_id: BaseResourceLocation) -> LoadedModel: - model_id = model_id.id + self._overridden_models.clear() + self._exceptions.clear() + try: + return self._render_model_recursive(model_id.id) + except Exception as e: + if self._exceptions: + # FIXME: hack + # necessary because of https://github.com/Textualize/rich/issues/1859 + group = ExceptionGroup( + "Caught errors while rendering model", + self._exceptions, + ) + traceback = "".join(TracebackException.from_exception(group).format()) + if e.args: + e.args = (f"{e.args[0]}\n{traceback}", *e.args[1:]) + else: + e.args = (traceback,) + raise e + finally: + self._overridden_models.clear() + self._exceptions.clear() + + def _render_model_recursive(self, model_id: ResourceLocation): logger.debug(f"Rendering model: {model_id}") - for override_id in self._get_overrides(model_id): - logger.debug(f"Attempting override: {override_id}") - for strategy in self._model_strategies: - logger.debug(f"Attempting model strategy: {strategy.__name__}") - try: - if result := strategy(override_id): - self._model_cache[model_id] = result - self._model_cache[override_id] = result - return result - except Exception: - # TODO: probably shouldn't just swallow all errors like this. - logger.debug( - f"Exception while rendering override: {override_id}", - exc_info=True, - ) + for strategy in self._model_strategies: + logger.debug(f"Attempting model strategy: {strategy.__name__}") + try: + if result := strategy(model_id): + self._model_cache[model_id] = result + return result + except Exception as e: + logger.debug( + f"Exception while rendering override: {model_id}", + exc_info=True, + ) + self._exceptions.append(e) raise ValueError(f"Failed to render model: {model_id}") @@ -92,10 +115,6 @@ def render_texture(self, texture_id: ResourceLocation) -> URL: except FileNotFoundError: raise ValueError(f"Failed to find texture: {texture_id}") - def _get_overrides(self, model_id: ResourceLocation): - # TODO: implement (maybe) - yield model_id - def _load_model(self, model_id: ResourceLocation) -> LoadedModel | BlockModel: if result := self._model_cache.get(model_id): logger.debug(f"Cache hit: {model_id} = {result}") @@ -183,7 +202,33 @@ def _from_renderer(self, model_id: ResourceLocation): model = self._load_model(model_id) if not isinstance(model, BlockModel): return model - fragment = self._get_fragment(model_id) + + try: + return self._from_model(model) + except Exception as e: + logger.debug(f"Failed to render model {model.id}: {e}") + self._exceptions.append(e) + + if not model.overrides: + return None + + if model.id in self._overridden_models: + logger.debug(f"Skipping override check for recursive override: {model.id}") + return None + self._overridden_models.add(model.id) + + # TODO: implement a smarter way of choosing an override? + n = len(model.overrides) + for i, override in enumerate(model.overrides): + logger.debug(f"Rendering model override ({i+1}/{n}): {override.model}") + try: + return self._render_model_recursive(override.model) + except Exception as e: + logger.debug(f"Failed to render override {override.model}: {e}") + self._exceptions.append(e) + + def _from_model(self, model: BlockModel): + fragment = self._get_fragment(model.id) suffix, image_type = self.renderer.render_model(model, self.site_dir / fragment) return LoadedModel( self._fragment_to_url(fragment.with_suffix(suffix)), From a2dad47d491abe0c2c6caf3af06bf004bfd4b74d Mon Sep 17 00:00:00 2001 From: object-Object Date: Fri, 24 May 2024 18:36:41 -0400 Subject: [PATCH 063/106] Fix incorrect configdict import from copier --- pyproject.toml | 1 + src/hexdoc/model/types.py | 3 +-- typings/copier.pyi | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 typings/copier.pyi diff --git a/pyproject.toml b/pyproject.toml index 7d29a49a..c7782f8d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -188,6 +188,7 @@ include = [ ] extraPaths = [ "vendor", + "typings", ] exclude = [ "noxfile.py", diff --git a/src/hexdoc/model/types.py b/src/hexdoc/model/types.py index bac99709..528300b7 100644 --- a/src/hexdoc/model/types.py +++ b/src/hexdoc/model/types.py @@ -3,8 +3,7 @@ import textwrap from typing import Any, ClassVar, Sequence -from copier import ConfigDict -from pydantic import field_validator, model_validator +from pydantic import ConfigDict, field_validator, model_validator from pydantic.dataclasses import dataclass from pydantic.fields import FieldInfo from typing_extensions import Unpack diff --git a/typings/copier.pyi b/typings/copier.pyi new file mode 100644 index 00000000..f066a13b --- /dev/null +++ b/typings/copier.pyi @@ -0,0 +1 @@ +# this is to prevent Pyright from suggesting imports from Copier From 4f0b4bce263aa12bd5f7243dbeb8f08bdf37d664 Mon Sep 17 00:00:00 2001 From: object-Object Date: Fri, 24 May 2024 18:43:05 -0400 Subject: [PATCH 064/106] Un-genericify HexdocImage --- src/hexdoc/graphics/validators.py | 33 +++++++++++++------------------ 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 28d29d2f..800cd9d0 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -2,7 +2,7 @@ import logging from abc import ABC, abstractmethod -from typing import TYPE_CHECKING, Annotated, Any, Generic +from typing import TYPE_CHECKING, Annotated, Any from pydantic import ( Field, @@ -37,8 +37,6 @@ _T = TypeVar("_T") -_T_ResourceLocation = TypeVar("_T_ResourceLocation", default=ResourceLocation) - class _ImageFieldType: def __class_getitem__(cls, item: Any) -> Any: @@ -66,16 +64,10 @@ class ImageField(_ImageFieldType): pass -class HexdocImage( - TemplateModel, - MustBeAnnotated, - Generic[_T_ResourceLocation], - ABC, - annotation=ImageField, -): +class HexdocImage(TemplateModel, MustBeAnnotated, ABC, annotation=ImageField): """An image that can be rendered in a hexdoc web book.""" - id: _T_ResourceLocation + id: ResourceLocation _name: LocalizedStr = PrivateAttr() @@ -115,7 +107,7 @@ def _set_name(self, info: ValidationInfo): return self -class URLImage(HexdocImage[_T_ResourceLocation], template_id="hexdoc:single"): +class URLImage(HexdocImage, template_id="hexdoc:single"): url: PydanticURL pixelated: bool = True @@ -125,7 +117,7 @@ def first_url(self): return self.url -class TextureImage(URLImage[ResourceLocation], InlineModel): +class TextureImage(URLImage, InlineModel): @override @classmethod def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: @@ -154,7 +146,9 @@ def _get_name(self, info: ValidationInfo): return LocalizedStr.with_value(str(self.id)) -class ItemImage(HexdocImage[ItemStack], InlineItemModel, UnionModel, ABC): +class ItemImage(HexdocImage, InlineItemModel, UnionModel, ABC): + item: ItemStack + @override @classmethod @abstractmethod @@ -168,7 +162,7 @@ def load_id(cls, item: ItemStack, context: dict[str, Any]) -> Any: ) -class SingleItemImage(URLImage[ItemStack], ItemImage): +class SingleItemImage(URLImage, ItemImage): model: BlockModel | None @override @@ -176,7 +170,8 @@ class SingleItemImage(URLImage[ItemStack], ItemImage): def load_id(cls, item: ItemStack, context: dict[str, Any]) -> Any: result = ImageLoader.of(context).render_item(item) return cls( - id=item, + id=item.id, + item=item, url=result.url, model=result.model, pixelated=result.image_type.pixelated, @@ -187,8 +182,8 @@ def _get_name(self, info: ValidationInfo): return I18n.of(info).localize_item(self.id) -class CyclingImage(HexdocImage[_T_ResourceLocation], template_id="hexdoc:cycling"): - images: SkipValidation[list[HexdocImage]] = Field(min_length=1) +class CyclingImage(HexdocImage, template_id="hexdoc:cycling"): + images: SkipValidation[list[HexdocImage[Any]]] = Field(min_length=1) @property @override @@ -200,7 +195,7 @@ def _get_name(self, info: ValidationInfo): return self.images[0].name -class TagImage(URLImage[ResourceLocation], InlineModel): +class TagImage(URLImage, InlineModel): @override @classmethod def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: From fbf44e789c7dde3dc7bc484316aae54d3f0a9bdd Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 12:49:13 -0400 Subject: [PATCH 065/106] Remove hexdoc.minecraft.assets and replace all usages of the old texture system --- .../assets/hexdoc/lang/en_us.flatten.json5 | 4 +- .../assets/hexdoc/lang/zh_cn.flatten.json5 | 4 +- .../_templates/macros/formatting.html.jinja | 6 +- .../_templates/macros/images.html.jinja | 13 + .../_templates/macros/recipes.html.jinja | 4 +- .../pages/patchouli/image.html.jinja | 8 +- .../pages/patchouli/multiblock.html.jinja | 4 +- .../pages/patchouli/spotlight.html.jinja | 6 +- src/hexdoc/_templates/recipes/base.html.jinja | 4 +- .../recipes/minecraft/furnace.html.jinja | 6 +- .../minecraft/smithing_table.html.jinja | 10 +- .../recipes/minecraft/stonecutter.html.jinja | 4 +- .../_templates/redirects/category.html.jinja | 4 +- .../_templates/redirects/entry.html.jinja | 4 +- src/hexdoc/cli/app.py | 22 +- src/hexdoc/cli/utils/__init__.py | 4 +- src/hexdoc/cli/utils/load.py | 41 +-- src/hexdoc/data/__init__.py | 6 +- src/hexdoc/data/metadata.py | 19 +- src/hexdoc/graphics/__init__.py | 10 +- src/hexdoc/graphics/validators.py | 19 +- src/hexdoc/jinja/filters.py | 30 +- src/hexdoc/minecraft/assets/__init__.py | 54 --- src/hexdoc/minecraft/assets/animated.py | 62 ---- src/hexdoc/minecraft/assets/constants.py | 13 - src/hexdoc/minecraft/assets/items.py | 52 --- src/hexdoc/minecraft/assets/load_assets.py | 324 ------------------ src/hexdoc/minecraft/assets/models.py | 178 ---------- src/hexdoc/minecraft/assets/textures.py | 103 ------ src/hexdoc/minecraft/assets/with_texture.py | 109 ------ src/hexdoc/minecraft/recipe/ingredients.py | 16 +- src/hexdoc/minecraft/recipe/recipes.py | 24 +- src/hexdoc/patchouli/category.py | 4 +- src/hexdoc/patchouli/entry.py | 4 +- src/hexdoc/patchouli/page/pages.py | 27 +- src/hexdoc/plugin/mod_plugin.py | 22 +- src/hexdoc_modonomicon/category.py | 4 +- src/hexdoc_modonomicon/entry.py | 4 +- submodules/HexMod | 2 +- test/minecraft/assets/test_with_texture.py | 28 +- test/templates/pages/patchouli/test_image.py | 6 +- 41 files changed, 161 insertions(+), 1107 deletions(-) delete mode 100644 src/hexdoc/minecraft/assets/__init__.py delete mode 100644 src/hexdoc/minecraft/assets/animated.py delete mode 100644 src/hexdoc/minecraft/assets/constants.py delete mode 100644 src/hexdoc/minecraft/assets/items.py delete mode 100644 src/hexdoc/minecraft/assets/load_assets.py delete mode 100644 src/hexdoc/minecraft/assets/models.py delete mode 100644 src/hexdoc/minecraft/assets/textures.py delete mode 100644 src/hexdoc/minecraft/assets/with_texture.py diff --git a/src/hexdoc/_export/resources/assets/hexdoc/lang/en_us.flatten.json5 b/src/hexdoc/_export/resources/assets/hexdoc/lang/en_us.flatten.json5 index 99ef78da..e9fddeb1 100644 --- a/src/hexdoc/_export/resources/assets/hexdoc/lang/en_us.flatten.json5 +++ b/src/hexdoc/_export/resources/assets/hexdoc/lang/en_us.flatten.json5 @@ -43,12 +43,12 @@ when_clicked: "When clicked, would execute: {}", - any_block: "Any Block", - redirect: { "category.title": "Category: {}", "entry.title": "Entry: {}", "page.title": "Page: {}", } }, + + "gui.hexdoc.any_block": "Any Block", } diff --git a/src/hexdoc/_export/resources/assets/hexdoc/lang/zh_cn.flatten.json5 b/src/hexdoc/_export/resources/assets/hexdoc/lang/zh_cn.flatten.json5 index 9d32f92d..cb15a17f 100644 --- a/src/hexdoc/_export/resources/assets/hexdoc/lang/zh_cn.flatten.json5 +++ b/src/hexdoc/_export/resources/assets/hexdoc/lang/zh_cn.flatten.json5 @@ -43,12 +43,12 @@ when_clicked: "点击时执行:{}", - any_block: "任意方块", - redirect: { "category.title": "类别:{}", "entry.title": "条目:{}", "page.title": "页面:{}", } }, + + "gui.hexdoc.any_block": "任意方块", } diff --git a/src/hexdoc/_templates/macros/formatting.html.jinja b/src/hexdoc/_templates/macros/formatting.html.jinja index b5665653..c10fb20e 100644 --- a/src/hexdoc/_templates/macros/formatting.html.jinja +++ b/src/hexdoc/_templates/macros/formatting.html.jinja @@ -1,6 +1,6 @@ {% import "macros/styles.html.jinja" as styles_html with context %} -{% import "macros/textures.html.jinja" as texture_macros with context %} {% import "macros/formatting.jinja" as fmt_base with context %} +{% import "macros/images.html.jinja" as Images with context -%} {# jump to top icon in section headers #} {% macro jump_to_top() -%} @@ -23,7 +23,7 @@ {# header for categories and entries #} {% macro section_header(value, header_tag, class_name) -%} <{{ header_tag }} class="{{ class_name }} page-header"> - {{ texture_macros.render_icon(value.icon) }} + {{ Images.item(value.icon) }} {{- value.name ~ jump_to_top() ~ permalink(value.id.path) -}} {%- endmacro %} @@ -31,7 +31,7 @@ {# link to value.id, with spoiler blur if value is a spoiler #} {% macro maybe_spoilered_link(value) -%} - {{- texture_macros.render_icon(value.icon) }} {{ value.name -}} + {{- Images.item(value.icon) }} {{ value.name -}} {%- endmacro %} diff --git a/src/hexdoc/_templates/macros/images.html.jinja b/src/hexdoc/_templates/macros/images.html.jinja index 12791979..55293bda 100644 --- a/src/hexdoc/_templates/macros/images.html.jinja +++ b/src/hexdoc/_templates/macros/images.html.jinja @@ -10,3 +10,16 @@
{{ count }}
{%- endif %} {%- endmacro %} + +{% macro recipe_gui(recipe, class_names=[]) -%} + {{ image( + recipe.gui_texture, + name=recipe.gui_name, + class_names=class_names, + lazy=false, + ) }} +{%- endmacro %} + +{% macro url(image) -%} + {{ site_url }}/{{ image.first_url }} +{%- endmacro %} diff --git a/src/hexdoc/_templates/macros/recipes.html.jinja b/src/hexdoc/_templates/macros/recipes.html.jinja index 91fbe12c..a7c381de 100644 --- a/src/hexdoc/_templates/macros/recipes.html.jinja +++ b/src/hexdoc/_templates/macros/recipes.html.jinja @@ -1,4 +1,4 @@ -{% import "macros/textures.html.jinja" as texture_macros with context -%} +{% import "macros/images.html.jinja" as Images with context -%} {% import "macros/formatting.html.jinja" as fmt with context -%} {# show the names of all the recipe results in a list of recipes #} @@ -21,7 +21,7 @@ {{ render_ingredients(ingredient.default, true) }} {{ render_ingredients(ingredient.if_loaded, true) }} {% else %} - {{ texture_macros.render_item(ingredient.item, is_first=loop.first and not is_recursive) }} + {{ Images.item(ingredient.item, is_first=loop.first and not is_recursive) }} {% endif %} {% endfor %} {%- endmacro %} diff --git a/src/hexdoc/_templates/pages/patchouli/image.html.jinja b/src/hexdoc/_templates/pages/patchouli/image.html.jinja index 865173d4..bdac9c3a 100644 --- a/src/hexdoc/_templates/pages/patchouli/image.html.jinja +++ b/src/hexdoc/_templates/pages/patchouli/image.html.jinja @@ -1,14 +1,14 @@ {% extends "pages/patchouli/text.html.jinja" %} -{% import "macros/textures.html.jinja" as texture_macros with context %} +{% import "macros/images.html.jinja" as Images with context -%} {% block inner_body %}

{% for image in page.images %} {#- TODO: figure out a better default name if there's no title #} {{ - texture_macros.render_texture( + Images.image( name=page.title or "", - texture=image, + image=image, lazy=false, ) }} @@ -18,7 +18,7 @@ {% endblock inner_body %} {% block redirect_image -%} - {{ texture_macros.texture_url(page.images|first) }} + {{ Images.url(page.images|first) }} {%- endblock redirect_image %} {% block redirect_extra_opengraph %} diff --git a/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja b/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja index 48681768..336f4bf3 100644 --- a/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja +++ b/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja @@ -1,5 +1,5 @@ {% extends "pages/patchouli/text.html.jinja" %} -{% import "macros/textures.html.jinja" as texture_macros with context %} +{% import "macros/images.html.jinja" as Images with context -%} {% import "macros/formatting.html.jinja" as fmt with context -%} {% block inner_body %} @@ -16,7 +16,7 @@ alt="Spotlight inventory slot" src="{{ 'hexdoc:textures/gui/spotlight.png'|hexdoc_texture }}" > - {{ texture_macros.render_item(item) }} + {{ Images.item(item) }} {{ count }}x {{ item.name }} diff --git a/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja b/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja index 7cc5b421..43a5e6eb 100644 --- a/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja +++ b/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja @@ -1,5 +1,5 @@ {% extends "pages/patchouli/text.html.jinja" %} -{% import "macros/textures.html.jinja" as texture_macros with context -%} +{% import "macros/images.html.jinja" as Images with context -%} {% block inner_body %}

@@ -8,11 +8,11 @@ alt="Spotlight inventory slot" src="{{ 'hexdoc:textures/gui/spotlight.png'|hexdoc_texture }}" > - {{ texture_macros.render_item(page.item) }} + {{ Images.item(page.item) }} {{ super() }} {% endblock inner_body %} {% block redirect_image -%} - {{ texture_macros.item_url(page.item) }} + {{ Images.url(page.item) }} {%- endblock redirect_image %} diff --git a/src/hexdoc/_templates/recipes/base.html.jinja b/src/hexdoc/_templates/recipes/base.html.jinja index 376060fc..120f07b9 100644 --- a/src/hexdoc/_templates/recipes/base.html.jinja +++ b/src/hexdoc/_templates/recipes/base.html.jinja @@ -1,4 +1,4 @@ -{% import "macros/textures.html.jinja" as texture_macros with context -%} +{% import "macros/images.html.jinja" as Images with context -%}
{% block title %} @@ -10,7 +10,7 @@ {% block recipe %}
{% block gui %} - {{ texture_macros.render_recipe_gui(recipe) }} + {{ Images.recipe_gui(recipe) }} {% endblock%} {% block content %}{% endblock %} diff --git a/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja b/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja index 40054cb5..f4b102b9 100644 --- a/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja +++ b/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja @@ -1,7 +1,7 @@ {% extends "recipes/base.html.jinja" %} {% import "macros/recipes.html.jinja" as recipe_macros with context %} -{% import "macros/textures.html.jinja" as texture_macros with context %} +{% import "macros/images.html.jinja" as Images with context -%} {% import "macros/formatting.html.jinja" as fmt with context %} {% block recipe_class -%} @@ -18,7 +18,7 @@
- {{ texture_macros.render_item(recipe.result) }} + {{ Images.item(recipe.result) }}
{{ extra_info( @@ -39,7 +39,7 @@ {# TODO: move somewhere more sensible #} {% macro extra_info(item_id, text, classes="") -%}
- {{ texture_macros.render_item(item_id|hexdoc_item)}} + {{ Images.item(item_id|hexdoc_item)}} {{ text }}
{%- endmacro %} diff --git a/src/hexdoc/_templates/recipes/minecraft/smithing_table.html.jinja b/src/hexdoc/_templates/recipes/minecraft/smithing_table.html.jinja index e3f16be8..672a722f 100644 --- a/src/hexdoc/_templates/recipes/minecraft/smithing_table.html.jinja +++ b/src/hexdoc/_templates/recipes/minecraft/smithing_table.html.jinja @@ -1,7 +1,7 @@ {% extends "recipes/base.html.jinja" %} {% import "macros/recipes.html.jinja" as recipe_macros with context %} -{% import "macros/textures.html.jinja" as texture_macros with context %} +{% import "macros/images.html.jinja" as Images with context -%} {% import "macros/formatting.html.jinja" as fmt with context %} {% block recipe_class -%} @@ -14,16 +14,16 @@ {% block content %}
- {{ texture_macros.render_item(recipe.base.item) }} + {{ Images.item(recipe.base.item) }}
- {{ texture_macros.render_item(recipe.addition.item) }} + {{ Images.item(recipe.addition.item) }}
- {{ texture_macros.render_item(recipe.template_ingredient.item) }} + {{ Images.item(recipe.template_ingredient.item) }}
- {{ texture_macros.render_item(recipe.result_item) }} + {{ Images.item(recipe.result_item) }}
{% endblock content %} diff --git a/src/hexdoc/_templates/recipes/minecraft/stonecutter.html.jinja b/src/hexdoc/_templates/recipes/minecraft/stonecutter.html.jinja index 19242fdb..ddbe555e 100644 --- a/src/hexdoc/_templates/recipes/minecraft/stonecutter.html.jinja +++ b/src/hexdoc/_templates/recipes/minecraft/stonecutter.html.jinja @@ -1,7 +1,7 @@ {% extends "recipes/base.html.jinja" %} {% import "macros/recipes.html.jinja" as recipe_macros with context %} -{% import "macros/textures.html.jinja" as texture_macros with context %} +{% import "macros/images.html.jinja" as Images with context -%} {% block recipe_class -%} stonecutting-recipe recipe @@ -17,6 +17,6 @@
- {{ texture_macros.render_item(recipe.result, count=recipe.count) }} + {{ Images.item(recipe.result, count=recipe.count) }}
{% endblock content %} diff --git a/src/hexdoc/_templates/redirects/category.html.jinja b/src/hexdoc/_templates/redirects/category.html.jinja index 7708a7f3..5a0265e8 100644 --- a/src/hexdoc/_templates/redirects/category.html.jinja +++ b/src/hexdoc/_templates/redirects/category.html.jinja @@ -1,7 +1,7 @@ {% extends "redirects/book_link.html.jinja" %} {% import "macros/formatting.txt.jinja" as fmt_txt with context %} -{% import "macros/textures.html.jinja" as texture_macros with context %} +{% import "macros/images.html.jinja" as Images with context %} {% block title -%} {{ _('hexdoc.redirect.category.title').format(category.name) }} @@ -12,5 +12,5 @@ {%- endblock description %} {% block image -%} - {{ texture_macros.icon_url(category.icon) }} + {{ Images.url(category.icon) }} {%- endblock image %} diff --git a/src/hexdoc/_templates/redirects/entry.html.jinja b/src/hexdoc/_templates/redirects/entry.html.jinja index 10d4a621..374b5413 100644 --- a/src/hexdoc/_templates/redirects/entry.html.jinja +++ b/src/hexdoc/_templates/redirects/entry.html.jinja @@ -1,7 +1,7 @@ {% extends "redirects/book_link.html.jinja" %} {% import "macros/formatting.txt.jinja" as fmt_txt with context %} -{% import "macros/textures.html.jinja" as texture_macros with context %} +{% import "macros/images.html.jinja" as Images with context %} {% block title -%} {{ _('hexdoc.redirect.entry.title').format(entry.name) }} @@ -12,5 +12,5 @@ {%- endblock description %} {% block image -%} - {{ texture_macros.icon_url(entry.icon) }} + {{ Images.url(entry.icon) }} {%- endblock image %} diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index f5a1b5fb..803b6d80 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -25,7 +25,6 @@ from hexdoc.graphics.loader import ImageLoader from hexdoc.jinja.render import create_jinja_env, get_templates, render_book from hexdoc.minecraft import I18n -from hexdoc.minecraft.assets import AnimatedTexture, PNGTexture, TextureContext from hexdoc.patchouli import BookContext, FormattingContext from hexdoc.plugin import ModPluginWithBook from hexdoc.utils import git_root, setup_logging, write_to_path @@ -43,9 +42,9 @@ VerbosityOption, ) from .utils.load import ( + export_metadata, init_context, load_common_data, - render_textures_and_export_metadata, ) logger = logging.getLogger(__name__) @@ -208,14 +207,6 @@ def build( site_path = plugin.site_path(versioned=release) site_dir = output_dir / site_path - asset_loader = plugin.asset_loader( - loader=loader, - site_url=props.env.github_pages_url.joinpath(*site_path.parts), - asset_url=props.env.asset_url, - render_dir=site_dir, - ) - asset_loader.renderer = renderer - image_loader = ImageLoader( loader=loader, renderer=renderer, @@ -223,7 +214,10 @@ def build( site_url=URL().joinpath(*site_path.parts), ) - all_metadata = render_textures_and_export_metadata(loader, asset_loader) + all_metadata = export_metadata( + loader, + site_url=props.env.github_pages_url.joinpath(*site_path.parts), + ) # FIXME: put this somewhere saner? logger.info("Exporting all image-related resources.") @@ -306,7 +300,6 @@ def build( book_ctx = BookContext.of(book_info.context) formatting_ctx = FormattingContext.of(book_info.context) - texture_ctx = TextureContext.of(book_info.context) site_book_path = plugin.site_book_path( book_info.language, @@ -317,11 +310,6 @@ def build( template_args: dict[str, Any] = book_info.context | { "all_metadata": all_metadata, - "png_textures": PNGTexture.get_lookup(texture_ctx.textures), - "animations": sorted( # this MUST be sorted to avoid flaky tests - AnimatedTexture.get_lookup(texture_ctx.textures).values(), - key=lambda t: t.css_class, - ), "book": book_info.book, "book_links": book_ctx.book_links, } diff --git a/src/hexdoc/cli/utils/__init__.py b/src/hexdoc/cli/utils/__init__.py index 991f23df..21f4dae1 100644 --- a/src/hexdoc/cli/utils/__init__.py +++ b/src/hexdoc/cli/utils/__init__.py @@ -1,15 +1,15 @@ __all__ = [ "DefaultTyper", + "export_metadata", "init_context", "load_common_data", - "render_textures_and_export_metadata", ] from .args import ( DefaultTyper, ) from .load import ( + export_metadata, init_context, load_common_data, - render_textures_and_export_metadata, ) diff --git a/src/hexdoc/cli/utils/load.py b/src/hexdoc/cli/utils/load.py index 3ee1ae3c..3470a9c0 100644 --- a/src/hexdoc/cli/utils/load.py +++ b/src/hexdoc/cli/utils/load.py @@ -4,8 +4,7 @@ from textwrap import indent from typing import Any, Literal, overload -from tqdm import tqdm -from tqdm.contrib.logging import logging_redirect_tqdm +from yarl import URL from hexdoc.core import ( MinecraftVersion, @@ -13,17 +12,9 @@ Properties, ResourceLocation, ) -from hexdoc.data import HexdocMetadata, load_metadata_textures +from hexdoc.data import HexdocMetadata from hexdoc.graphics.loader import ImageLoader from hexdoc.minecraft import I18n, Tag -from hexdoc.minecraft.assets import ( - AnimatedTexture, - HexdocAssetLoader, - PNGTexture, - Texture, - TextureContext, - TextureLookups, -) from hexdoc.model import init_context as set_init_context from hexdoc.patchouli import BookContext from hexdoc.patchouli.text import DEFAULT_MACROS, FormattingContext @@ -76,33 +67,13 @@ def load_common_data( return props, pm, book_plugin, mod_plugin -def render_textures_and_export_metadata( - loader: ModResourceLoader, - asset_loader: HexdocAssetLoader, -): +def export_metadata(loader: ModResourceLoader, site_url: URL): all_metadata = loader.load_metadata(model_type=HexdocMetadata) - all_lookups = load_metadata_textures(all_metadata) - image_textures = { - id: texture - for texture_type in [PNGTexture, AnimatedTexture] - for id, texture in texture_type.get_lookup(all_lookups).items() - } - - internal_lookups = TextureLookups[Texture](dict) - if loader.props.textures.enabled: - logger.info(f"Loading and rendering textures to {asset_loader.render_dir}.") - with logging_redirect_tqdm(): - bar = tqdm(asset_loader.load_and_render_internal_textures(image_textures)) - for id, texture in bar: - bar.set_postfix_str(str(id)) - texture.insert_texture(internal_lookups, id) - # this mod's metadata metadata = HexdocMetadata( - book_url=asset_loader.site_url / loader.props.default_lang, + book_url=site_url / loader.props.default_lang, asset_url=loader.props.env.asset_url, - textures=internal_lookups, ) loader.export( @@ -143,10 +114,6 @@ def init_context( loader, image_loader, i18n, - TextureContext( - textures=load_metadata_textures(all_metadata), - allowed_missing_textures=props.textures.missing, - ), FormattingContext( book_id=book_id, macros=DEFAULT_MACROS | book_data.get("macros", {}) | props.macros, diff --git a/src/hexdoc/data/__init__.py b/src/hexdoc/data/__init__.py index 5f50e4d0..729f8d7b 100644 --- a/src/hexdoc/data/__init__.py +++ b/src/hexdoc/data/__init__.py @@ -1,3 +1,5 @@ -__all__ = ["HexdocMetadata", "load_metadata_textures"] +__all__ = [ + "HexdocMetadata", +] -from .metadata import HexdocMetadata, load_metadata_textures +from .metadata import HexdocMetadata diff --git a/src/hexdoc/data/metadata.py b/src/hexdoc/data/metadata.py index cf55c0f2..ccede92b 100644 --- a/src/hexdoc/data/metadata.py +++ b/src/hexdoc/data/metadata.py @@ -1,29 +1,20 @@ from pathlib import Path -from hexdoc.minecraft.assets import Texture, TextureLookups -from hexdoc.model import HexdocModel -from hexdoc.utils.types import PydanticURL +from hexdoc.model import IGNORE_EXTRA_CONFIG, HexdocModel +from hexdoc.utils import PydanticURL class HexdocMetadata(HexdocModel): """Automatically generated at `export_dir/modid.hexdoc.json`.""" + # fields have been removed from the metadata; this makes it not a breaking change + model_config = IGNORE_EXTRA_CONFIG + book_url: PydanticURL | None """Github Pages base url.""" asset_url: PydanticURL """raw.githubusercontent.com base url.""" - textures: TextureLookups[Texture] @classmethod def path(cls, modid: str) -> Path: return Path(f"{modid}.hexdoc.json") - - -def load_metadata_textures(all_metadata: dict[str, HexdocMetadata]): - lookups = TextureLookups[Texture](dict) - - for metadata in all_metadata.values(): - for classname, lookup in metadata.textures.items(): - lookups[classname] |= lookup - - return lookups diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index 5c287b1d..ac767f56 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -1,5 +1,6 @@ __all__ = [ "DebugType", + "HexdocImage", "ImageField", "ImageLoader", "ItemImage", @@ -14,4 +15,11 @@ from .renderer import ModelRenderer from .texture import ModelTexture from .utils import DebugType -from .validators import ImageField, ItemImage, MissingImage, TagImage, TextureImage +from .validators import ( + HexdocImage, + ImageField, + ItemImage, + MissingImage, + TagImage, + TextureImage, +) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 800cd9d0..33792b81 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -8,6 +8,7 @@ Field, PrivateAttr, SkipValidation, + TypeAdapter, ValidationError, ValidationInfo, WrapValidator, @@ -29,7 +30,14 @@ ) from hexdoc.model.types import MustBeAnnotated from hexdoc.plugin import PluginManager -from hexdoc.utils import Inherit, InheritType, PydanticURL, classproperty +from hexdoc.utils import ( + ContextSource, + Inherit, + InheritType, + PydanticURL, + cast_context, + classproperty, +) from .loader import MISSING_TEXTURE_ID, TAG_TEXTURE_ID, ImageLoader @@ -212,3 +220,12 @@ def _get_name(self, info: ValidationInfo): def _validate_id(cls, id: ResourceLocation): assert id.is_tag, f"Expected tag id, got {id}" return id + + +def validate_image( + model_type: type[_T] | Any, + value: Any, + context: ContextSource, +) -> _T | MissingImage: + ta = TypeAdapter(ImageField[model_type]) + return ta.validate_python(value, context=cast_context(context)) diff --git a/src/hexdoc/jinja/filters.py b/src/hexdoc/jinja/filters.py index 89491006..3711a63e 100644 --- a/src/hexdoc/jinja/filters.py +++ b/src/hexdoc/jinja/filters.py @@ -1,5 +1,5 @@ import functools -from typing import Any, Callable, ParamSpec, TypeVar, cast +from typing import Callable, ParamSpec, TypeVar from jinja2 import pass_context from jinja2.runtime import Context @@ -7,12 +7,13 @@ from hexdoc.core import Properties, ResourceLocation from hexdoc.core.resource import ItemStack -from hexdoc.minecraft import I18n -from hexdoc.minecraft.assets import ( - ItemWithTexture, - PNGTexture, - validate_texture, +from hexdoc.graphics.validators import ( + ItemImage, + MissingImage, + TextureImage, + validate_image, ) +from hexdoc.minecraft import I18n from hexdoc.patchouli import FormatTree from hexdoc.plugin import PluginManager @@ -81,16 +82,12 @@ def hexdoc_localize( return formatted -# TODO: support the full texture lookup +# TODO: rename to hexdoc_texture_url @pass_context @make_jinja_exceptions_suck_a_bit_less def hexdoc_texture(context: Context, id: str | ResourceLocation) -> str: - texture = validate_texture( - id, - context=context, - model_type=PNGTexture, - ) - return str(texture.url) + image = validate_image(TextureImage, id, context) + return str(image.url) @pass_context @@ -98,8 +95,5 @@ def hexdoc_texture(context: Context, id: str | ResourceLocation) -> str: def hexdoc_item( context: Context, id: str | ResourceLocation | ItemStack, -) -> ItemWithTexture: - return ItemWithTexture.model_validate( - id, - context=cast(dict[str, Any], context), # lie - ) +) -> ItemImage | MissingImage: + return validate_image(ItemImage, id, context) diff --git a/src/hexdoc/minecraft/assets/__init__.py b/src/hexdoc/minecraft/assets/__init__.py deleted file mode 100644 index c6b00dd0..00000000 --- a/src/hexdoc/minecraft/assets/__init__.py +++ /dev/null @@ -1,54 +0,0 @@ -__all__ = [ - "AnimatedTexture", - "AnimationMeta", - "HexdocAssetLoader", - "ImageTexture", - "ItemTexture", - "ItemWithTexture", - "ModelItem", - "MultiItemTexture", - "NamedTexture", - "PNGTexture", - "SingleItemTexture", - "TagWithTexture", - "Texture", - "TextureContext", - "TextureLookup", - "TextureLookups", - "validate_texture", -] - -from .animated import ( - AnimatedTexture, - AnimationMeta, -) -from .items import ( - ImageTexture, - ItemTexture, - MultiItemTexture, - SingleItemTexture, -) -from .load_assets import ( - HexdocAssetLoader, - Texture, - validate_texture, -) -from .models import ModelItem -from .textures import ( - PNGTexture, - TextureContext, - TextureLookup, - TextureLookups, -) -from .with_texture import ( - ItemWithTexture, - NamedTexture, - TagWithTexture, -) - -HexdocPythonResourceLoader = None -"""PLACEHOLDER - DO NOT USE - -This class has been removed from hexdoc, but this variable is required to fix an import -error with old versions of `hexdoc_minecraft`. -""" diff --git a/src/hexdoc/minecraft/assets/animated.py b/src/hexdoc/minecraft/assets/animated.py deleted file mode 100644 index 3207a995..00000000 --- a/src/hexdoc/minecraft/assets/animated.py +++ /dev/null @@ -1,62 +0,0 @@ -from __future__ import annotations - -from functools import cached_property -from typing import Any, Self - -from hexdoc.model import HexdocModel -from hexdoc.utils.types import PydanticURL - -from ..model.animation import AnimationMeta -from .textures import BaseTexture - - -class AnimatedTextureFrame(HexdocModel): - index: int - start: int - time: int - animation_time: int - - @property - def start_percent(self): - return self._format_time(self.start) - - @property - def end_percent(self): - return self._format_time(self.start + self.time, backoff=True) - - def _format_time(self, time: int, *, backoff: bool = False) -> str: - percent = 100 * time / self.animation_time - if backoff and percent < 100: - percent -= 0.01 - return f"{percent:.2f}".rstrip("0").rstrip(".") - - -class AnimatedTexture(BaseTexture): - url: PydanticURL | None - pixelated: bool - css_class: str - meta: AnimationMeta - - @classmethod - def from_url(cls, *args: Any, **kwargs: Any) -> Self: - raise NotImplementedError("AnimatedTexture does not support from_url()") - - @property - def time_seconds(self): - return self.time / 20 - - @cached_property - def time(self): - return sum(frame.time for frame in self.meta.animation.frames) - - @property - def frames(self): - start = 0 - for frame in self.meta.animation.frames: - yield AnimatedTextureFrame( - index=frame.index, - start=start, - time=frame.time, - animation_time=self.time, - ) - start += frame.time diff --git a/src/hexdoc/minecraft/assets/constants.py b/src/hexdoc/minecraft/assets/constants.py deleted file mode 100644 index 7a982fe7..00000000 --- a/src/hexdoc/minecraft/assets/constants.py +++ /dev/null @@ -1,13 +0,0 @@ -# 16x16 hashtag icon for tags -from yarl import URL - -TAG_TEXTURE_URL = URL( - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAC4jAAAuIwF4pT92AAAANUlEQVQ4y2NgGJRAXV39v7q6+n9cfGTARKllFBvAiOxMUjTevHmTkSouGPhAHA0DWnmBrgAANLIZgSXEQxIAAAAASUVORK5CYII=" -) - -# purple and black square -MISSING_TEXTURE_URL = URL( - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAC4jAAAuIwF4pT92AAAAJElEQVQoz2NkwAF+MPzAKs7EQCIY1UAMYMQV3hwMHKOhRD8NAPogBA/DVsDEAAAAAElFTkSuQmCC" -) - -NUM_GASLIGHTING_TEXTURES = 4 diff --git a/src/hexdoc/minecraft/assets/items.py b/src/hexdoc/minecraft/assets/items.py deleted file mode 100644 index 061f3a8a..00000000 --- a/src/hexdoc/minecraft/assets/items.py +++ /dev/null @@ -1,52 +0,0 @@ -from __future__ import annotations - -from typing import Self - -from yarl import URL - -from hexdoc.core import ItemStack, ResourceLocation -from hexdoc.utils import ContextSource - -from .animated import AnimatedTexture -from .textures import BaseTexture, PNGTexture - -ImageTexture = PNGTexture | AnimatedTexture - - -# this needs to be a separate class, rather than just using ImageTexture directly, -# because the key in the lookup for SingleItemTexture is the item id, not the texture id -class SingleItemTexture(BaseTexture): - inner: ImageTexture - - @classmethod - def from_url(cls, url: URL, pixelated: bool) -> Self: - return cls( - inner=PNGTexture(url=url, pixelated=pixelated), - ) - - @classmethod - def load_id(cls, id: ResourceLocation | ItemStack, context: ContextSource): - return super().load_id(id.id, context) - - @property - def url(self): - return self.inner.url - - -class MultiItemTexture(BaseTexture): - inner: list[ImageTexture] - gaslighting: bool - - @classmethod - def from_url(cls, url: URL, pixelated: bool) -> Self: - return cls( - inner=[PNGTexture(url=url, pixelated=pixelated)], - gaslighting=False, - ) - - @classmethod - def load_id(cls, id: ResourceLocation | ItemStack, context: ContextSource): - return super().load_id(id.id, context) - - -ItemTexture = SingleItemTexture | MultiItemTexture diff --git a/src/hexdoc/minecraft/assets/load_assets.py b/src/hexdoc/minecraft/assets/load_assets.py deleted file mode 100644 index 891f40bf..00000000 --- a/src/hexdoc/minecraft/assets/load_assets.py +++ /dev/null @@ -1,324 +0,0 @@ -import logging -import textwrap -from collections.abc import Set -from dataclasses import dataclass, field -from functools import cached_property -from pathlib import Path -from typing import Any, Iterable, Iterator, TypeVar, cast - -from pydantic import TypeAdapter -from yarl import URL - -from hexdoc.core import ModResourceLoader, ResourceLocation -from hexdoc.core.properties import ( - PNGTextureOverride, - TextureTextureOverride, -) -from hexdoc.graphics import ModelRenderer -from hexdoc.utils import PydanticURL -from hexdoc.utils.context import ContextSource - -from ..model.animation import AnimationMeta -from ..tags import Tag -from .animated import AnimatedTexture -from .constants import MISSING_TEXTURE_URL -from .items import ( - ImageTexture, - ItemTexture, - MultiItemTexture, - SingleItemTexture, -) -from .models import FoundNormalTexture, ModelItem -from .textures import PNGTexture - -logger = logging.getLogger(__name__) - -Texture = ImageTexture | ItemTexture - -_T_Texture = TypeVar("_T_Texture", bound=Texture) - - -def validate_texture( - value: Any, - *, - context: ContextSource, - model_type: type[_T_Texture] | Any = Texture, -) -> _T_Texture: - ta = TypeAdapter(model_type) - return ta.validate_python( - value, - context=cast(dict[str, Any], context), # lie - ) - - -class TextureNotFoundError(FileNotFoundError): - def __init__(self, id_type: str, id: ResourceLocation): - self.message = f"No texture found for {id_type} id: {id}" - super().__init__(self.message) - - -@dataclass(kw_only=True) -class HexdocAssetLoader: - loader: ModResourceLoader - site_url: PydanticURL - asset_url: PydanticURL - render_dir: Path - - # FIXME: so so so awfully hacky. i hate it here - renderer: ModelRenderer = field(init=False) - - @cached_property - def gaslighting_items(self): - return Tag.GASLIGHTING_ITEMS.load(self.loader).value_ids_set - - @property - def texture_props(self): - return self.loader.props.textures - - def can_be_missing(self, id: ResourceLocation): - if self.texture_props.missing == "*": - return True - return any(id.match(pattern) for pattern in self.texture_props.missing) - - def get_override( - self, - id: ResourceLocation, - image_textures: dict[ResourceLocation, ImageTexture], - ) -> Texture | None: - match self.texture_props.override.get(id): - case PNGTextureOverride(url=url, pixelated=pixelated): - return PNGTexture(url=url, pixelated=pixelated) - case TextureTextureOverride(texture=texture): - return image_textures[texture] - case None: - return None - - def find_image_textures( - self, - ) -> Iterable[tuple[ResourceLocation, Path | ImageTexture]]: - for resource_dir, texture_id, path in self.loader.find_resources( - "assets", - namespace="*", - folder="textures", - glob="**/*.png", - internal_only=True, - allow_missing=True, - ): - if resource_dir: - self.loader.export_raw( - path=path.relative_to(resource_dir.path), - data=path.read_bytes(), - ) - yield texture_id, path - - def load_item_models(self) -> Iterable[tuple[ResourceLocation, ModelItem]]: - for _, item_id, data in self.loader.load_resources( - "assets", - namespace="*", - folder="models/item", - internal_only=True, - allow_missing=True, - ): - model = ModelItem.load_data("item" / item_id, data) - yield item_id, model - - def fallback_texture(self, item_id: ResourceLocation) -> ItemTexture | None: - return None - - def load_and_render_internal_textures( - self, - image_textures: dict[ResourceLocation, ImageTexture], - ) -> Iterator[tuple[ResourceLocation, Texture]]: - """For all item/block models in all internal resource dirs, yields the item id - (eg. `hexcasting:focus`) and some kind of texture that we can use in the book.""" - - # images - for texture_id, value in self.find_image_textures(): - if not texture_id.path.startswith("textures"): - texture_id = "textures" / texture_id - - match value: - case Path() as path: - texture = load_texture( - texture_id, - path=path, - repo_root=self.loader.props.repo_root, - asset_url=self.asset_url, - strict=self.texture_props.strict, - ) - - case PNGTexture() | AnimatedTexture() as texture: - pass - - image_textures[texture_id] = texture - yield texture_id, texture - - found_items_from_models = set[ResourceLocation]() - missing_items = set[ResourceLocation]() - - missing_item_texture = SingleItemTexture.from_url( - MISSING_TEXTURE_URL, pixelated=True - ) - - # items - for item_id, model in self.load_item_models(): - if result := self.get_override(item_id, image_textures): - yield item_id, result - elif result := load_and_render_item( - model, - self.loader, - self.renderer, - self.gaslighting_items, - image_textures, - self.site_url, - self.render_dir, - ): - found_items_from_models.add(item_id) - yield item_id, result - else: - missing_items.add(item_id) - - for item_id in list(missing_items): - if result := self.fallback_texture(item_id): - logger.warning(f"Using fallback texture for item: {item_id}") - elif self.can_be_missing(item_id): - logger.warning(f"Using missing texture for item: {item_id}") - result = missing_item_texture - else: - continue - missing_items.remove(item_id) - yield item_id, result - - # oopsies - if missing_items: - raise FileNotFoundError( - "Failed to find a texture for some items: " - + ", ".join(sorted(str(item) for item in missing_items)) - ) - - -def load_texture( - id: ResourceLocation, - *, - path: Path, - repo_root: Path, - asset_url: URL, - strict: bool, -) -> ImageTexture: - # FIXME: is_relative_to is only false when reading zip archives. ideally we would - # permalink to the gh-pages branch and copy all textures there, but we can't get - # that commit until we build the book, so it's a bit of a circular dependency. - if path.is_relative_to(repo_root): - url = asset_url.joinpath(*path.relative_to(repo_root).parts) - else: - level = logging.WARNING if strict else logging.DEBUG - logger.log(level, f"Failed to find relative path for {id}: {path}") - url = None - - meta_path = path.with_suffix(".png.mcmeta") - if meta_path.is_file(): - try: - meta = AnimationMeta.model_validate_json(meta_path.read_bytes()) - except ValueError as e: - logger.debug(f"Failed to parse AnimationMeta for {id}\n{e}") - else: - return AnimatedTexture( - url=url, - pixelated=True, - css_class=id.css_class, - meta=meta, - ) - - return PNGTexture(url=url, pixelated=True) - - -def load_and_render_item( - model: ModelItem, - loader: ModResourceLoader, - renderer: ModelRenderer, - gaslighting_items: Set[ResourceLocation], - image_textures: dict[ResourceLocation, ImageTexture], - site_url: URL, - output_dir: Path, -) -> ItemTexture | None: - try: - match model.find_texture(loader, gaslighting_items): - case None: - return None - - case "gaslighting", found_textures: - textures = list( - lookup_or_render_single_item( - found_texture, - renderer, - image_textures, - site_url, - output_dir, - ).inner - for found_texture in found_textures - ) - return MultiItemTexture(inner=textures, gaslighting=True) - - case found_texture: - texture = lookup_or_render_single_item( - found_texture, - renderer, - image_textures, - site_url, - output_dir, - ) - return texture - except TextureNotFoundError as e: - logger.warning(e.message) - return None - - -# TODO: move to methods on a class returned by find_texture? -def lookup_or_render_single_item( - found_texture: FoundNormalTexture, - renderer: ModelRenderer, - image_textures: dict[ResourceLocation, ImageTexture], - site_url: URL, - output_dir: Path, -) -> SingleItemTexture: - match found_texture: - case "texture", texture_id: - if texture_id not in image_textures: - raise TextureNotFoundError("item", texture_id) - return SingleItemTexture(inner=image_textures[texture_id]) - - case "block_model", model_id: - return render_block(model_id, renderer, site_url, output_dir) - - -def render_block( - id: ResourceLocation, - renderer: ModelRenderer, - site_url: URL, - output_dir: Path, -) -> SingleItemTexture: - # FIXME: hack - id_out_path = id.path - if id.path.startswith("item/"): - id_out_path = "block/" + id.path.removeprefix("item/") - elif not id.path.startswith("block/"): - id = "block" / id - - out_path = f"assets/{id.namespace}/textures/{id_out_path}.png" - - try: - # FIXME: scuffed - suffix, _ = renderer.render_model(id, output_dir / out_path) - out_path = out_path.removesuffix(".png") + suffix - except Exception as e: - if renderer.loader.props.textures.strict: - raise - message = textwrap.indent(f"{e.__class__.__name__}: {e}", " ") - logger.error(f"Failed to render block {id}:\n{message}") - raise TextureNotFoundError("block", id) - - logger.debug(f"Rendered {id} to {out_path}") - - # TODO: ideally we shouldn't be using site_url here, in case the site is moved - # but I'm not sure what else we could do... - return SingleItemTexture.from_url(site_url / out_path, pixelated=False) diff --git a/src/hexdoc/minecraft/assets/models.py b/src/hexdoc/minecraft/assets/models.py deleted file mode 100644 index e2b90ddf..00000000 --- a/src/hexdoc/minecraft/assets/models.py +++ /dev/null @@ -1,178 +0,0 @@ -from __future__ import annotations - -import logging -from collections import defaultdict -from collections.abc import Set -from typing import Annotated, Any, Literal - -from hexdoc.core import ModResourceLoader, ResourceLocation -from hexdoc.model import HexdocModel -from hexdoc.utils import JSONDict, clamping_validator - -logger = logging.getLogger(__name__) - -FoundNormalTexture = tuple[Literal["texture", "block_model"], ResourceLocation] -FoundGaslightingTexture = tuple[Literal["gaslighting"], list[FoundNormalTexture]] -FoundTexture = FoundNormalTexture | FoundGaslightingTexture - -ItemDisplayPosition = Literal[ - "thirdperson_righthand", - "thirdperson_lefthand", - "firstperson_righthand", - "firstperson_lefthand", - "gui", - "head", - "ground", - "fixed", -] - -_Translation = Annotated[float, clamping_validator(-80, 80)] -_Scale = Annotated[float, clamping_validator(-4, 4)] - - -class ItemDisplay(HexdocModel): - rotation: tuple[float, float, float] | None = None - translation: tuple[_Translation, _Translation, _Translation] | None = None - scale: tuple[_Scale, _Scale, _Scale] | None = None - - -class ModelOverride(HexdocModel): - model: ResourceLocation - """The id of the model to use if the case is met.""" - predicate: dict[ResourceLocation, float] - - -# allow missing because mods can add custom fields :/ -class ModelItem(HexdocModel, extra="allow"): - """https://minecraft.wiki/w/Tutorials/Models#Item_models - - This is called BaseModelItem instead of BaseItemModel because SomethingModel is our - naming convention for abstract Pydantic models. - """ - - id: ResourceLocation - """Not in the actual file.""" - - parent: ResourceLocation | None = None - """Loads a different model with the given id.""" - display: dict[ItemDisplayPosition, ItemDisplay] | None = None - gui_light: Literal["front", "side"] = "side" - overrides: list[ModelOverride] | None = None - # TODO: minecraft_render would need to support this - elements: Any | None = None - # TODO: support texture variables etc? - textures: dict[str, ResourceLocation] | None = None - """Texture ids. For example, `{"layer0": "item/red_bed"}` refers to the resource - `assets/minecraft/textures/item/red_bed.png`. - - Technically this is only allowed for `minecraft:item/generated`, but we're currently - not loading Minecraft's item models, so there's lots of other parent ids that this - field can show up for. - """ - - @classmethod - def load_resource(cls, id: ResourceLocation, loader: ModResourceLoader): - _, data = loader.load_resource("assets", "models", id, export=False) - return cls.load_data(id, data) - - @classmethod - def load_data(cls, id: ResourceLocation, data: JSONDict): - return cls.model_validate(data | {"id": id}) - - @property - def item_id(self): - if "/" not in self.id.path: - return self.id - path_without_prefix = "/".join(self.id.path.split("/")[1:]) - return self.id.with_path(path_without_prefix) - - @property - def layer0(self): - if self.textures: - return self.textures.get("layer0") - - def find_texture( - self, - loader: ModResourceLoader, - gaslighting_items: Set[ResourceLocation], - checked_overrides: defaultdict[ResourceLocation, set[int]] | None = None, - ) -> FoundTexture | None: - """May return a texture **or** a model. Texture ids will start with `textures/`.""" - if checked_overrides is None: - checked_overrides = defaultdict(set) - - # gaslighting - # as of 0.11.1-7, all gaslighting item models are implemented with overrides - if self.item_id in gaslighting_items: - if not self.overrides: - raise ValueError( - f"Model {self.id} for item {self.item_id} marked as gaslighting but" - " does not have overrides" - ) - - gaslighting_textures = list[FoundNormalTexture]() - for i, override in enumerate(self.overrides): - match self._find_override_texture( - i, override, loader, gaslighting_items, checked_overrides - ): - case "gaslighting", _: - raise ValueError( - f"Model {self.id} for item {self.item_id} marked as" - f" gaslighting but override {i} resolves to another gaslighting texture" - ) - case None: - break - case result: - gaslighting_textures.append(result) - else: - return "gaslighting", gaslighting_textures - - # if it exists, the layer0 texture is *probably* representative - # TODO: impl multi-layer textures for Sam - if self.layer0: - texture_id = "textures" / self.layer0 + ".png" - return "texture", texture_id - - # first resolvable override, if any - for i, override in enumerate(self.overrides or []): - if result := self._find_override_texture( - i, override, loader, gaslighting_items, checked_overrides - ): - return result - - if self.parent and self.parent.path.startswith("block/"): - # try the parent id - # we only do this for blocks in the same namespace because most other - # parents are generic "base class"-type models which won't actually - # represent the item - if self.parent.namespace == self.id.namespace: - return "block_model", self.parent - - # FIXME: hack - # this entire selection process needs to be redone, but the idea here is to - # try rendering item models as blocks in certain cases (eg. edified button) - return "block_model", self.id - - return None - - def _find_override_texture( - self, - index: int, - override: ModelOverride, - loader: ModResourceLoader, - gaslighting_items: Set[ResourceLocation], - checked_overrides: defaultdict[ResourceLocation, set[int]], - ) -> FoundTexture | None: - if override.model.path.startswith("block/"): - return "block_model", override.model - - if index in checked_overrides[self.id]: - logger.debug(f"Ignoring recursive override: {override.model}") - return None - - checked_overrides[self.id].add(index) - return ( - (ModelItem) - .load_resource(override.model, loader) - .find_texture(loader, gaslighting_items, checked_overrides) - ) diff --git a/src/hexdoc/minecraft/assets/textures.py b/src/hexdoc/minecraft/assets/textures.py deleted file mode 100644 index 532cc289..00000000 --- a/src/hexdoc/minecraft/assets/textures.py +++ /dev/null @@ -1,103 +0,0 @@ -from __future__ import annotations - -import logging -from abc import ABC, abstractmethod -from collections import defaultdict -from typing import ( - Annotated, - Any, - Iterable, - Literal, - Self, - TypeVar, -) - -from pydantic import Field, SerializeAsAny -from typing_extensions import override -from yarl import URL - -from hexdoc.core import ResourceLocation -from hexdoc.model import ( - InlineModel, - ValidationContextModel, -) -from hexdoc.utils import ContextSource, PydanticURL - -from .constants import MISSING_TEXTURE_URL - -logger = logging.getLogger(__name__) - - -class BaseTexture(InlineModel, ABC): - @classmethod - @abstractmethod - def from_url(cls, url: URL, pixelated: bool) -> Self: ... - - @override - @classmethod - def load_id(cls, id: ResourceLocation, context: ContextSource): - texture_ctx = TextureContext.of(context) - return cls.lookup( - id, - lookups=texture_ctx.textures, - allowed_missing=texture_ctx.allowed_missing_textures, - ) - - @classmethod - def lookup( - cls, - id: ResourceLocation, - lookups: TextureLookups[Any], - allowed_missing: Iterable[ResourceLocation] | Literal["*"], - ) -> Self: - """Returns the texture from the lookup table if it exists, or the "missing - texture" texture if it's in `props.texture.missing`, or raises `ValueError`. - - This is called frequently and does not load any files. - """ - textures = cls.get_lookup(lookups) - if id in textures: - return textures[id] - - # TODO: this logic is duplicated in load_assets.py :/ - if allowed_missing == "*" or any( - id.match(pattern) for pattern in allowed_missing - ): - logger.warning(f"No {cls.__name__} for {id}, using default missing texture") - return cls.from_url(MISSING_TEXTURE_URL, pixelated=True) - - raise ValueError(f"No {cls.__name__} for {id}") - - @classmethod - def get_lookup(cls, lookups: TextureLookups[Any]) -> TextureLookup[Self]: - return lookups[cls.__name__] - - def insert_texture(self, lookups: TextureLookups[Any], id: ResourceLocation): - textures = self.get_lookup(lookups) - textures[id] = self - - -class PNGTexture(BaseTexture): - url: PydanticURL | None - pixelated: bool - - @classmethod - def from_url(cls, url: URL, pixelated: bool) -> Self: - return cls(url=url, pixelated=pixelated) - - -_T_BaseTexture = TypeVar("_T_BaseTexture", bound=BaseTexture) - -TextureLookup = dict[ResourceLocation, SerializeAsAny[_T_BaseTexture]] -"""dict[id, texture]""" - -TextureLookups = defaultdict[ - str, - Annotated[TextureLookup[_T_BaseTexture], Field(default_factory=dict)], -] -"""dict[type(texture).__name__, TextureLookup]""" - - -class TextureContext(ValidationContextModel): - textures: TextureLookups[Any] - allowed_missing_textures: set[ResourceLocation] | Literal["*"] diff --git a/src/hexdoc/minecraft/assets/with_texture.py b/src/hexdoc/minecraft/assets/with_texture.py deleted file mode 100644 index ff699b00..00000000 --- a/src/hexdoc/minecraft/assets/with_texture.py +++ /dev/null @@ -1,109 +0,0 @@ -from __future__ import annotations - -import logging -from typing import Generic, TypeVar - -from pydantic import field_validator - -from hexdoc.core import ( - ItemStack, - ResourceLocation, -) -from hexdoc.core.resource import BaseResourceLocation -from hexdoc.model import ( - HexdocModel, - InlineItemModel, - InlineModel, -) -from hexdoc.utils import ContextSource - -from ..i18n import I18n, LocalizedStr -from .animated import AnimatedTexture -from .constants import TAG_TEXTURE_URL -from .items import ImageTexture, ItemTexture, MultiItemTexture, SingleItemTexture -from .load_assets import Texture -from .textures import PNGTexture - -logger = logging.getLogger(__name__) - -_T_BaseResourceLocation = TypeVar("_T_BaseResourceLocation", bound=BaseResourceLocation) - -_T_Texture = TypeVar("_T_Texture", bound=Texture) - - -class BaseWithTexture(HexdocModel, Generic[_T_BaseResourceLocation, _T_Texture]): - id: _T_BaseResourceLocation - name: LocalizedStr - texture: Texture - - @property - def image_texture(self) -> ImageTexture | None: - match self.texture: - case PNGTexture() | AnimatedTexture(): - return self.texture - case SingleItemTexture(): - return self.texture.inner - case MultiItemTexture(): - return None - - @property - def image_textures(self) -> list[ImageTexture] | None: - match self.texture: - case MultiItemTexture(): - return self.texture.inner - case PNGTexture() | AnimatedTexture() | SingleItemTexture(): - return None - - @property - def gaslighting(self) -> bool: - match self.texture: - case MultiItemTexture(): - return self.texture.gaslighting - case PNGTexture() | AnimatedTexture() | SingleItemTexture(): - return False - - -class ItemWithTexture(InlineItemModel, BaseWithTexture[ItemStack, ItemTexture]): - @classmethod - def load_id(cls, item: ItemStack, context: ContextSource): - """Implements InlineModel.""" - - i18n = I18n.of(context) - if item.path.startswith("texture"): - name = i18n.localize_texture(item.id) - else: - name = i18n.localize_item(item) - - return { - "id": item, - "name": name, - "texture": item.id, # TODO: fix InlineModel (ItemTexture), then remove .id - } - - -class TagWithTexture(InlineModel, BaseWithTexture[ResourceLocation, Texture]): - @classmethod - def load_id(cls, id: ResourceLocation, context: ContextSource): - i18n = I18n.of(context) - return cls( - id=id, - name=i18n.localize_item_tag(id), - texture=PNGTexture.from_url(TAG_TEXTURE_URL, pixelated=True), - ) - - @field_validator("id", mode="after") - @classmethod - def _validate_id(cls, id: ResourceLocation): - assert id.is_tag, f"Expected tag id, got {id}" - return id - - -class NamedTexture(InlineModel, BaseWithTexture[ResourceLocation, ImageTexture]): - @classmethod - def load_id(cls, id: ResourceLocation, context: ContextSource): - i18n = I18n.of(context) - return { - "id": id, - "name": i18n.localize_texture(id, silent=True), - "texture": id, - } diff --git a/src/hexdoc/minecraft/recipe/ingredients.py b/src/hexdoc/minecraft/recipe/ingredients.py index 1d342ed5..b332b9c5 100644 --- a/src/hexdoc/minecraft/recipe/ingredients.py +++ b/src/hexdoc/minecraft/recipe/ingredients.py @@ -9,23 +9,21 @@ ValidationInfo, ) -from hexdoc.core import ResourceLocation -from hexdoc.core.loader import ModResourceLoader -from hexdoc.core.resource import AssumeTag +from hexdoc.core import AssumeTag, ModResourceLoader, ResourceLocation +from hexdoc.graphics import HexdocImage, ImageField, ItemImage, TagImage from hexdoc.model import HexdocModel, NoValue, TypeTaggedUnion from hexdoc.utils import listify -from ..assets import ItemWithTexture, TagWithTexture from ..tags import Tag class ItemIngredient(TypeTaggedUnion, ABC): @property - def item(self) -> ItemWithTexture | TagWithTexture: ... + def item(self) -> HexdocImage: ... class MinecraftItemIdIngredient(ItemIngredient, type=NoValue): - item_: ItemWithTexture = Field(alias="item") + item_: ImageField[ItemImage] = Field(alias="item") @property def item(self): @@ -33,7 +31,7 @@ def item(self): class MinecraftItemTagIngredient(ItemIngredient, type=NoValue): - tag: AssumeTag[TagWithTexture] + tag: ImageField[AssumeTag[TagImage]] @property def item(self): @@ -41,7 +39,7 @@ def item(self): class ItemResult(HexdocModel): - item: ItemWithTexture + item: ImageField[ItemImage] count: int = 1 @@ -63,7 +61,7 @@ def _validate_flatten_nested_tags( yield ingredient if isinstance(ingredient, MinecraftItemTagIngredient): - yield from _items_in_tag(ingredient.tag.id, info, loader) + yield from _items_in_tag(ingredient.tag.id.id, info, loader) def _items_in_tag( diff --git a/src/hexdoc/minecraft/recipe/recipes.py b/src/hexdoc/minecraft/recipe/recipes.py index c6224e2c..166d77ce 100644 --- a/src/hexdoc/minecraft/recipe/recipes.py +++ b/src/hexdoc/minecraft/recipe/recipes.py @@ -1,6 +1,13 @@ from typing import ClassVar, Iterator, Unpack -from pydantic import ConfigDict, Field, PrivateAttr, ValidationInfo, model_validator +from pydantic import ( + ConfigDict, + Field, + PrivateAttr, + TypeAdapter, + ValidationInfo, + model_validator, +) from typing_extensions import override from hexdoc.core import ( @@ -9,10 +16,10 @@ ValueIfVersion, ) from hexdoc.core.compat import AtLeast_1_20, Before_1_20 +from hexdoc.graphics import HexdocImage, ImageField, ItemImage, TextureImage from hexdoc.model import ResourceModel, TypeTaggedTemplate from hexdoc.utils import Inherit, InheritType, classproperty -from ..assets import ImageTexture, ItemWithTexture, validate_texture from ..i18n import I18n, LocalizedStr from .ingredients import ItemIngredient, ItemIngredientList, ItemResult @@ -34,7 +41,7 @@ class Recipe(TypeTaggedTemplate, ResourceModel): _workstation: ClassVar[ResourceLocation | None] = None _gui_name: LocalizedStr | None = PrivateAttr(None) - _gui_texture: ImageTexture | None = PrivateAttr(None) + _gui_texture: HexdocImage | None = PrivateAttr(None) def __init_subclass__( cls, @@ -98,10 +105,9 @@ def _load_gui_texture(self, info: ValidationInfo): self._gui_name = self._localize_workstation(I18n.of(info)) if self._gui_texture_id is not None: - self._gui_texture = validate_texture( + self._gui_texture = TypeAdapter(ImageField[TextureImage]).validate_python( self._gui_texture_id, - context=info, - model_type=ImageTexture, + context=info.context, ) return self @@ -134,7 +140,7 @@ def ingredients(self) -> Iterator[ItemIngredientList | None]: class CookingRecipe(Recipe): ingredient: ItemIngredientList - result: ItemWithTexture + result: ImageField[ItemImage] experience: float cookingtime: int @@ -182,7 +188,7 @@ def result_item(self): class SmithingTransformRecipe(SmithingRecipe, type="minecraft:smithing_transform"): - result: ItemWithTexture + result: ImageField[ItemImage] @property def result_item(self): @@ -199,5 +205,5 @@ class StonecuttingRecipe( workstation="minecraft:stonecutter", ): ingredient: ItemIngredientList - result: ItemWithTexture + result: ImageField[ItemImage] count: int diff --git a/src/hexdoc/patchouli/category.py b/src/hexdoc/patchouli/category.py index ed9bad3c..baa5362b 100644 --- a/src/hexdoc/patchouli/category.py +++ b/src/hexdoc/patchouli/category.py @@ -5,8 +5,8 @@ from hexdoc.core import ResourceLocation from hexdoc.core.loader import ModResourceLoader +from hexdoc.graphics import ImageField, ItemImage, TextureImage from hexdoc.minecraft import LocalizedStr -from hexdoc.minecraft.assets import ItemWithTexture, NamedTexture from hexdoc.model import IDModel from hexdoc.utils import Sortable, sorted_dict from hexdoc.utils.graphs import TypedDiGraph @@ -27,7 +27,7 @@ class Category(IDModel, Sortable): # required name: LocalizedStr description: FormatTree - icon: ItemWithTexture | NamedTexture + icon: ImageField[ItemImage | TextureImage] # optional parent_id: ResourceLocation | None = Field(default=None, alias="parent") diff --git a/src/hexdoc/patchouli/entry.py b/src/hexdoc/patchouli/entry.py index 9729298d..5aaeca33 100644 --- a/src/hexdoc/patchouli/entry.py +++ b/src/hexdoc/patchouli/entry.py @@ -3,8 +3,8 @@ from pydantic import Field from hexdoc.core import ItemStack, ResourceLocation +from hexdoc.graphics import ImageField, ItemImage, TextureImage from hexdoc.minecraft import LocalizedStr -from hexdoc.minecraft.assets import ItemWithTexture, NamedTexture from hexdoc.minecraft.recipe import CraftingRecipe from hexdoc.model import Color, IDModel from hexdoc.utils import Sortable @@ -23,7 +23,7 @@ class Entry(IDModel, Sortable, AdvancementSpoilered): # required (entry.json) name: LocalizedStr category_id: ResourceLocation = Field(alias="category") - icon: ItemWithTexture | NamedTexture + icon: ImageField[ItemImage | TextureImage] pages: list[Page] # optional (entry.json) diff --git a/src/hexdoc/patchouli/page/pages.py b/src/hexdoc/patchouli/page/pages.py index bb89b9ec..29c7010d 100644 --- a/src/hexdoc/patchouli/page/pages.py +++ b/src/hexdoc/patchouli/page/pages.py @@ -3,9 +3,10 @@ from pydantic import ValidationInfo, field_validator, model_validator -from hexdoc.core import Entity, ItemStack, ResourceLocation -from hexdoc.minecraft import I18n, LocalizedStr -from hexdoc.minecraft.assets import ItemWithTexture, PNGTexture, TagWithTexture, Texture +from hexdoc.core import Entity, ResourceLocation +from hexdoc.graphics import ImageField, ItemImage, TextureImage +from hexdoc.graphics.validators import TagImage +from hexdoc.minecraft import LocalizedStr from hexdoc.minecraft.recipe import ( BlastingRecipe, CampfireCookingRecipe, @@ -54,7 +55,7 @@ class EntityPage(PageWithText, type="patchouli:entity"): class ImagePage(PageWithTitle, type="patchouli:image"): - images: list[Texture] + images: list[ImageField[TextureImage]] border: bool = False @property @@ -74,7 +75,7 @@ class LinkPage(TextPage, type="patchouli:link"): class Multiblock(HexdocModel): """https://vazkiimods.github.io/Patchouli/docs/patchouli-basics/multiblocks/""" - mapping: dict[str, ItemWithTexture | TagWithTexture] + mapping: dict[str, ImageField[ItemImage | TextureImage]] pattern: list[list[str]] symmetrical: bool = False offset: tuple[int, int, int] | None = None @@ -110,18 +111,14 @@ def bill_of_materials(self): @classmethod def _add_default_mapping( cls, - mapping: dict[str, ItemWithTexture | TagWithTexture], + mapping: dict[str, ImageField[ItemImage | TagImage]], info: ValidationInfo, ): - i18n = I18n.of(info) return { - "_": ItemWithTexture( - id=ItemStack("hexdoc", "any"), - name=i18n.localize("hexdoc.any_block"), - texture=PNGTexture.load_id( - ResourceLocation("hexdoc", "textures/gui/any_block.png"), - context=info, - ), + # FIXME: this needs to be ItemImage somehow + "_": TextureImage.load_id( + id=ResourceLocation("hexdoc", "textures/gui/any_block.png"), + context=info.context or {}, ), } | mapping @@ -168,5 +165,5 @@ class StonecuttingPage( class SpotlightPage(PageWithTitle, type="patchouli:spotlight"): - item: ItemWithTexture + item: ImageField[ItemImage] link_recipe: bool = False diff --git a/src/hexdoc/plugin/mod_plugin.py b/src/hexdoc/plugin/mod_plugin.py index 9b1ba7ad..6d78b18e 100644 --- a/src/hexdoc/plugin/mod_plugin.py +++ b/src/hexdoc/plugin/mod_plugin.py @@ -8,16 +8,14 @@ from jinja2.sandbox import SandboxedEnvironment from typing_extensions import override -from yarl import URL from hexdoc.utils import ContextSource from .types import HookReturn if TYPE_CHECKING: - from hexdoc.core import ModResourceLoader, Properties + from hexdoc.core import Properties from hexdoc.graphics.validators import ItemImage - from hexdoc.minecraft.assets import HexdocAssetLoader DefaultRenderedTemplates = Mapping[ str | Path, @@ -182,24 +180,6 @@ def latest_site_path(self) -> Path: """ return self.site_root / "latest" / self.branch - def asset_loader( - self, - loader: ModResourceLoader, - *, - site_url: URL, - asset_url: URL, - render_dir: Path, - ) -> HexdocAssetLoader: - # unfortunately, this is necessary to avoid some *real* ugly circular imports - from hexdoc.minecraft.assets import HexdocAssetLoader - - return HexdocAssetLoader( - loader=loader, - site_url=site_url, - asset_url=asset_url, - render_dir=render_dir, - ) - class VersionedModPlugin(ModPlugin): """Like `ModPlugin`, but the versioned site path uses the plugin and mod version.""" diff --git a/src/hexdoc_modonomicon/category.py b/src/hexdoc_modonomicon/category.py index c2bf8fc9..ea7be980 100644 --- a/src/hexdoc_modonomicon/category.py +++ b/src/hexdoc_modonomicon/category.py @@ -1,6 +1,6 @@ from hexdoc.core import ResourceLocation +from hexdoc.graphics import ImageField, ItemImage, TextureImage from hexdoc.minecraft import LocalizedStr -from hexdoc.minecraft.assets import ItemWithTexture, NamedTexture from hexdoc.model import HexdocModel from pydantic import Field @@ -23,7 +23,7 @@ class Category(HexdocModel): """https://klikli-dev.github.io/modonomicon/docs/basics/structure/categories""" name: LocalizedStr - icon: ItemWithTexture | NamedTexture + icon: ImageField[ItemImage | TextureImage] sort_number: int = -1 condition: Condition | None = None diff --git a/src/hexdoc_modonomicon/entry.py b/src/hexdoc_modonomicon/entry.py index 8e4fc8f1..2134d942 100644 --- a/src/hexdoc_modonomicon/entry.py +++ b/src/hexdoc_modonomicon/entry.py @@ -1,6 +1,6 @@ from hexdoc.core import ResourceLocation +from hexdoc.graphics import ImageField, ItemImage, TextureImage from hexdoc.minecraft import LocalizedStr -from hexdoc.minecraft.assets import ItemWithTexture, NamedTexture from hexdoc.model import HexdocModel from pydantic import Field @@ -23,7 +23,7 @@ class Entry(HexdocModel): category: ResourceLocation name: LocalizedStr description: LocalizedStr - icon: ItemWithTexture | NamedTexture + icon: ImageField[ItemImage | TextureImage] x: int y: int diff --git a/submodules/HexMod b/submodules/HexMod index 29b18478..458b7f39 160000 --- a/submodules/HexMod +++ b/submodules/HexMod @@ -1 +1 @@ -Subproject commit 29b18478ac467da6eafd885baabf675330f52600 +Subproject commit 458b7f39a08679a8f24ea1e5fec28936629cb352 diff --git a/test/minecraft/assets/test_with_texture.py b/test/minecraft/assets/test_with_texture.py index 5dcdfdd3..f94d4895 100644 --- a/test/minecraft/assets/test_with_texture.py +++ b/test/minecraft/assets/test_with_texture.py @@ -1,12 +1,9 @@ -from collections import defaultdict from typing import Any import pytest from hexdoc.core import Properties from hexdoc.core.properties import LangProps -from hexdoc.core.resource import ResourceLocation -from hexdoc.minecraft.assets.textures import TextureContext -from hexdoc.minecraft.assets.with_texture import ItemWithTexture, TagWithTexture +from hexdoc.graphics import ItemImage, TagImage from hexdoc.minecraft.i18n import I18n from hexdoc.plugin import PluginManager from hexdoc.utils.context import ContextSource @@ -16,6 +13,7 @@ @pytest.fixture def context(): props = Properties.model_construct() + props.textures.strict = False pm = PluginManager("branch", props=props) i18n = I18n( @@ -32,25 +30,19 @@ def context(): lang_props=LangProps(), ) - texture_ctx = TextureContext( - textures=defaultdict(dict), - allowed_missing_textures={ - ResourceLocation("minecraft", "*"), - }, - ) - context: ContextSource = {} - for ctx in [props, pm, i18n, texture_ctx]: + for ctx in [props, pm, i18n]: ctx.add_to_context(context) return context +@pytest.mark.skip("Needs some effort to make it work with the new image loader") @pytest.mark.parametrize( "union", [ - ItemWithTexture | TagWithTexture, - TagWithTexture | ItemWithTexture, + ItemImage | TagImage, + TagImage | ItemImage, ], ids=[ "item_first", @@ -60,14 +52,14 @@ def context(): @pytest.mark.parametrize( ["data", "want_type"], [ - ["minecraft:gold", ItemWithTexture], - ["#minecraft:gold", TagWithTexture], + ["minecraft:gold", ItemImage], + ["#minecraft:gold", TagImage], ], ) def test_item_tag_union( - union: type[ItemWithTexture | TagWithTexture], + union: type[ItemImage | TagImage], data: Any, - want_type: type[ItemWithTexture | TagWithTexture], + want_type: type[ItemImage | TagImage], context: Any, ): ta = TypeAdapter(union) diff --git a/test/templates/pages/patchouli/test_image.py b/test/templates/pages/patchouli/test_image.py index cbed18ce..36eff047 100644 --- a/test/templates/pages/patchouli/test_image.py +++ b/test/templates/pages/patchouli/test_image.py @@ -2,10 +2,8 @@ from hexdoc.core.resource import ResourceLocation from hexdoc.jinja.render import create_jinja_env_with_loader -from hexdoc.minecraft.assets.textures import PNGTexture from hexdoc.patchouli.page.pages import ImagePage from jinja2 import PackageLoader -from yarl import URL def test_no_title(): @@ -18,8 +16,6 @@ def test_no_title(): id=ResourceLocation("entry_ns", "entry_path"), ), page=ImagePage.model_construct( - images=[ - PNGTexture(url=URL("https://example.com"), pixelated=True), - ], + images=[], ), ) From 364e3ceab4ed49345c164f855cfca322c036fdcf Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 12:51:21 -0400 Subject: [PATCH 066/106] Move model definitions from minecraft to graphics --- src/hexdoc/graphics/__init__.py | 2 ++ src/hexdoc/graphics/block.py | 10 +++++----- src/hexdoc/graphics/camera.py | 3 +-- src/hexdoc/graphics/loader.py | 2 +- src/hexdoc/graphics/lookups.py | 3 ++- src/hexdoc/{minecraft => graphics}/model/__init__.py | 0 src/hexdoc/{minecraft => graphics}/model/animation.py | 0 src/hexdoc/{minecraft => graphics}/model/block.py | 0 src/hexdoc/{minecraft => graphics}/model/blockstate.py | 0 src/hexdoc/{minecraft => graphics}/model/display.py | 0 src/hexdoc/{minecraft => graphics}/model/element.py | 0 src/hexdoc/graphics/renderer.py | 2 +- src/hexdoc/graphics/texture.py | 3 ++- src/hexdoc/graphics/validators.py | 2 +- 14 files changed, 15 insertions(+), 12 deletions(-) rename src/hexdoc/{minecraft => graphics}/model/__init__.py (100%) rename src/hexdoc/{minecraft => graphics}/model/animation.py (100%) rename src/hexdoc/{minecraft => graphics}/model/block.py (100%) rename src/hexdoc/{minecraft => graphics}/model/blockstate.py (100%) rename src/hexdoc/{minecraft => graphics}/model/display.py (100%) rename src/hexdoc/{minecraft => graphics}/model/element.py (100%) diff --git a/src/hexdoc/graphics/__init__.py b/src/hexdoc/graphics/__init__.py index ac767f56..59b01b9a 100644 --- a/src/hexdoc/graphics/__init__.py +++ b/src/hexdoc/graphics/__init__.py @@ -9,8 +9,10 @@ "ModelTexture", "TagImage", "TextureImage", + "model", ] +from . import model from .loader import ImageLoader from .renderer import ModelRenderer from .texture import ModelTexture diff --git a/src/hexdoc/graphics/block.py b/src/hexdoc/graphics/block.py index 3c0db773..eddac1b2 100644 --- a/src/hexdoc/graphics/block.py +++ b/src/hexdoc/graphics/block.py @@ -16,7 +16,11 @@ from PIL import Image from pyrr import Matrix44 -from hexdoc.minecraft.model import ( +from hexdoc.utils.types import Vec3, Vec4 + +from .camera import direction_camera +from .lookups import get_face_normals, get_face_uv_indices, get_face_verts +from .model import ( BlockModel, DisplayPosition, Element, @@ -24,10 +28,6 @@ ElementFaceUV, FaceName, ) -from hexdoc.utils.types import Vec3, Vec4 - -from .camera import direction_camera -from .lookups import get_face_normals, get_face_uv_indices, get_face_verts from .texture import ModelTexture from .utils import DebugType, get_rotation_matrix, read_shader diff --git a/src/hexdoc/graphics/camera.py b/src/hexdoc/graphics/camera.py index c85105a9..08018c45 100644 --- a/src/hexdoc/graphics/camera.py +++ b/src/hexdoc/graphics/camera.py @@ -7,9 +7,8 @@ from pyrr import Matrix44 -from hexdoc.minecraft.model import FaceName - from .lookups import get_direction_vec +from .model import FaceName from .utils import transform_vec diff --git a/src/hexdoc/graphics/loader.py b/src/hexdoc/graphics/loader.py index 530368a3..09e373c9 100644 --- a/src/hexdoc/graphics/loader.py +++ b/src/hexdoc/graphics/loader.py @@ -8,9 +8,9 @@ from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.core.resource import BaseResourceLocation -from hexdoc.minecraft.model import BlockModel from hexdoc.utils import ValidationContext +from .model import BlockModel from .renderer import ImageType, ModelRenderer from .texture import ModelTexture diff --git a/src/hexdoc/graphics/lookups.py b/src/hexdoc/graphics/lookups.py index 54ffdb91..8028d184 100644 --- a/src/hexdoc/graphics/lookups.py +++ b/src/hexdoc/graphics/lookups.py @@ -2,9 +2,10 @@ from __future__ import annotations -from hexdoc.minecraft.model import FaceName from hexdoc.utils.types import Vec3 +from .model import FaceName + def get_face_verts(from_: Vec3, to: Vec3, direction: FaceName): x1, y1, z1 = from_ diff --git a/src/hexdoc/minecraft/model/__init__.py b/src/hexdoc/graphics/model/__init__.py similarity index 100% rename from src/hexdoc/minecraft/model/__init__.py rename to src/hexdoc/graphics/model/__init__.py diff --git a/src/hexdoc/minecraft/model/animation.py b/src/hexdoc/graphics/model/animation.py similarity index 100% rename from src/hexdoc/minecraft/model/animation.py rename to src/hexdoc/graphics/model/animation.py diff --git a/src/hexdoc/minecraft/model/block.py b/src/hexdoc/graphics/model/block.py similarity index 100% rename from src/hexdoc/minecraft/model/block.py rename to src/hexdoc/graphics/model/block.py diff --git a/src/hexdoc/minecraft/model/blockstate.py b/src/hexdoc/graphics/model/blockstate.py similarity index 100% rename from src/hexdoc/minecraft/model/blockstate.py rename to src/hexdoc/graphics/model/blockstate.py diff --git a/src/hexdoc/minecraft/model/display.py b/src/hexdoc/graphics/model/display.py similarity index 100% rename from src/hexdoc/minecraft/model/display.py rename to src/hexdoc/graphics/model/display.py diff --git a/src/hexdoc/minecraft/model/element.py b/src/hexdoc/graphics/model/element.py similarity index 100% rename from src/hexdoc/minecraft/model/element.py rename to src/hexdoc/graphics/model/element.py diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index 252f1da1..a1ed978c 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -16,9 +16,9 @@ from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.core.properties import AnimationFormat -from hexdoc.minecraft.model import BlockModel from .block import BlockRenderer +from .model import BlockModel from .texture import ModelTexture from .utils import DebugType diff --git a/src/hexdoc/graphics/texture.py b/src/hexdoc/graphics/texture.py index be49152f..c82c4975 100644 --- a/src/hexdoc/graphics/texture.py +++ b/src/hexdoc/graphics/texture.py @@ -12,9 +12,10 @@ from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.core.properties import AnimatedTexturesProps -from hexdoc.minecraft.model import Animation, AnimationFrame, AnimationMeta from hexdoc.utils import listify +from .model import Animation, AnimationFrame, AnimationMeta + logger = logging.getLogger(__name__) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 33792b81..652bdf36 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -21,7 +21,6 @@ from hexdoc.core import ItemStack, Properties, ResourceLocation from hexdoc.minecraft.i18n import I18n, LocalizedStr -from hexdoc.minecraft.model import BlockModel from hexdoc.model import ( InlineItemModel, InlineModel, @@ -40,6 +39,7 @@ ) from .loader import MISSING_TEXTURE_ID, TAG_TEXTURE_ID, ImageLoader +from .model import BlockModel logger = logging.getLogger(__name__) From 367e7bf65b8046d8770eb8b6e6341955dbda77d1 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 13:05:01 -0400 Subject: [PATCH 067/106] Move i18n to hexdoc.core --- src/hexdoc/cli/app.py | 3 +-- src/hexdoc/cli/utils/load.py | 3 ++- src/hexdoc/core/__init__.py | 4 ++++ src/hexdoc/{minecraft => core}/i18n.py | 15 ++++++--------- src/hexdoc/graphics/validators.py | 10 ++++------ src/hexdoc/jinja/filters.py | 3 +-- src/hexdoc/jinja/render.py | 3 +-- src/hexdoc/minecraft/__init__.py | 7 ++++--- src/hexdoc/minecraft/recipe/ingredients.py | 2 +- src/hexdoc/minecraft/recipe/recipes.py | 3 ++- src/hexdoc/patchouli/book.py | 2 +- src/hexdoc/patchouli/category.py | 3 +-- src/hexdoc/patchouli/entry.py | 3 +-- src/hexdoc/patchouli/page/abstract_pages.py | 3 +-- src/hexdoc/patchouli/page/pages.py | 3 +-- src/hexdoc/patchouli/text.py | 3 +-- src/hexdoc/plugin/manager.py | 3 +-- src/hexdoc/plugin/specs.py | 3 +-- src/hexdoc_modonomicon/book.py | 3 +-- src/hexdoc_modonomicon/category.py | 3 +-- src/hexdoc_modonomicon/entry.py | 3 +-- submodules/HexMod | 2 +- test/integration/test_extend_book.py | 3 +-- test/integration/test_modpack.py | 3 +-- test/minecraft/assets/test_with_texture.py | 3 +-- test/minecraft/test_i18n.py | 3 +-- test/patchouli/test_text.py | 2 +- 27 files changed, 43 insertions(+), 58 deletions(-) rename src/hexdoc/{minecraft => core}/i18n.py (97%) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 803b6d80..96b8c5fb 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -17,14 +17,13 @@ from yarl import URL from hexdoc.__version__ import VERSION -from hexdoc.core import ModResourceLoader, ResourceLocation +from hexdoc.core import I18n, ModResourceLoader, ResourceLocation from hexdoc.core.properties import AnimationFormat from hexdoc.data.metadata import HexdocMetadata from hexdoc.data.sitemap import delete_updated_books, dump_sitemap, load_sitemap from hexdoc.graphics import DebugType, ModelRenderer from hexdoc.graphics.loader import ImageLoader from hexdoc.jinja.render import create_jinja_env, get_templates, render_book -from hexdoc.minecraft import I18n from hexdoc.patchouli import BookContext, FormattingContext from hexdoc.plugin import ModPluginWithBook from hexdoc.utils import git_root, setup_logging, write_to_path diff --git a/src/hexdoc/cli/utils/load.py b/src/hexdoc/cli/utils/load.py index 3470a9c0..647610cf 100644 --- a/src/hexdoc/cli/utils/load.py +++ b/src/hexdoc/cli/utils/load.py @@ -7,6 +7,7 @@ from yarl import URL from hexdoc.core import ( + I18n, MinecraftVersion, ModResourceLoader, Properties, @@ -14,7 +15,7 @@ ) from hexdoc.data import HexdocMetadata from hexdoc.graphics.loader import ImageLoader -from hexdoc.minecraft import I18n, Tag +from hexdoc.minecraft import Tag from hexdoc.model import init_context as set_init_context from hexdoc.patchouli import BookContext from hexdoc.patchouli.text import DEFAULT_MACROS, FormattingContext diff --git a/src/hexdoc/core/__init__.py b/src/hexdoc/core/__init__.py index d1771297..a097b94b 100644 --- a/src/hexdoc/core/__init__.py +++ b/src/hexdoc/core/__init__.py @@ -7,8 +7,11 @@ "BookFolder", "Entity", "ExportFn", + "I18n", "IsVersion", "ItemStack", + "LocalizedItem", + "LocalizedStr", "MinecraftVersion", "ModResourceLoader", "PathResourceDir", @@ -32,6 +35,7 @@ Versioned, VersionSource, ) +from .i18n import I18n, LocalizedItem, LocalizedStr from .loader import ( METADATA_SUFFIX, BookFolder, diff --git a/src/hexdoc/minecraft/i18n.py b/src/hexdoc/core/i18n.py similarity index 97% rename from src/hexdoc/minecraft/i18n.py rename to src/hexdoc/core/i18n.py index f8aafa73..30bc549b 100644 --- a/src/hexdoc/minecraft/i18n.py +++ b/src/hexdoc/core/i18n.py @@ -9,18 +9,15 @@ from pydantic import ValidationInfo, model_validator from pydantic.functional_validators import ModelWrapValidatorHandler -from hexdoc.core import ( - ItemStack, - ModResourceLoader, - ResourceLocation, - ValueIfVersion, -) -from hexdoc.core.properties import LangProps -from hexdoc.model import HexdocModel, ValidationContextModel -from hexdoc.model.base import DEFAULT_CONFIG +from hexdoc.model.base import DEFAULT_CONFIG, HexdocModel, ValidationContextModel from hexdoc.utils import decode_and_flatten_json_dict from hexdoc.utils.json_schema import inherited, json_schema_extra_config, type_str +from .compat import ValueIfVersion +from .loader import ModResourceLoader +from .properties import LangProps +from .resource import ItemStack, ResourceLocation + logger = logging.getLogger(__name__) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 652bdf36..3fc7f144 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -19,8 +19,7 @@ from typing_extensions import TypeVar, override from yarl import URL -from hexdoc.core import ItemStack, Properties, ResourceLocation -from hexdoc.minecraft.i18n import I18n, LocalizedStr +from hexdoc.core import I18n, ItemStack, LocalizedStr, Properties, ResourceLocation from hexdoc.model import ( InlineItemModel, InlineModel, @@ -141,10 +140,9 @@ class MissingImage(TextureImage, annotation=None): @override @classmethod def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: - message = f"Using missing texture for id: {id}" if Properties.of(context).textures.strict: - raise ValueError(message) - logger.warning(message) + raise ValueError(f"Failed to load image for id: {id}") + logger.warning(f"Using missing texture for id: {id}") url = ImageLoader.of(context).render_texture(MISSING_TEXTURE_ID) return cls(id=id, url=url, pixelated=True) @@ -191,7 +189,7 @@ def _get_name(self, info: ValidationInfo): class CyclingImage(HexdocImage, template_id="hexdoc:cycling"): - images: SkipValidation[list[HexdocImage[Any]]] = Field(min_length=1) + images: SkipValidation[list[HexdocImage]] = Field(min_length=1) @property @override diff --git a/src/hexdoc/jinja/filters.py b/src/hexdoc/jinja/filters.py index 3711a63e..e1f8c40f 100644 --- a/src/hexdoc/jinja/filters.py +++ b/src/hexdoc/jinja/filters.py @@ -5,7 +5,7 @@ from jinja2.runtime import Context from markupsafe import Markup -from hexdoc.core import Properties, ResourceLocation +from hexdoc.core import I18n, Properties, ResourceLocation from hexdoc.core.resource import ItemStack from hexdoc.graphics.validators import ( ItemImage, @@ -13,7 +13,6 @@ TextureImage, validate_image, ) -from hexdoc.minecraft import I18n from hexdoc.patchouli import FormatTree from hexdoc.plugin import PluginManager diff --git a/src/hexdoc/jinja/render.py b/src/hexdoc/jinja/render.py index a218b696..8adbbb88 100644 --- a/src/hexdoc/jinja/render.py +++ b/src/hexdoc/jinja/render.py @@ -18,10 +18,9 @@ ) from jinja2.sandbox import SandboxedEnvironment -from hexdoc.core import MinecraftVersion, Properties, ResourceLocation +from hexdoc.core import I18n, MinecraftVersion, Properties, ResourceLocation from hexdoc.core.properties import JINJA_NAMESPACE_ALIASES from hexdoc.data.sitemap import MARKER_NAME, LatestSitemapMarker, VersionedSitemapMarker -from hexdoc.minecraft import I18n from hexdoc.plugin import ModPluginWithBook, PluginManager from hexdoc.utils import ContextSource, write_to_path diff --git a/src/hexdoc/minecraft/__init__.py b/src/hexdoc/minecraft/__init__.py index 1583fd5a..45c2d2e4 100644 --- a/src/hexdoc/minecraft/__init__.py +++ b/src/hexdoc/minecraft/__init__.py @@ -4,10 +4,11 @@ "LocalizedStr", "Tag", "TagValue", - "assets", "recipe", ] -from . import assets, recipe -from .i18n import I18n, LocalizedItem, LocalizedStr +# for backwards compatibility +from hexdoc.core.i18n import I18n, LocalizedItem, LocalizedStr + +from . import recipe from .tags import Tag, TagValue diff --git a/src/hexdoc/minecraft/recipe/ingredients.py b/src/hexdoc/minecraft/recipe/ingredients.py index b332b9c5..84de4688 100644 --- a/src/hexdoc/minecraft/recipe/ingredients.py +++ b/src/hexdoc/minecraft/recipe/ingredients.py @@ -10,7 +10,7 @@ ) from hexdoc.core import AssumeTag, ModResourceLoader, ResourceLocation -from hexdoc.graphics import HexdocImage, ImageField, ItemImage, TagImage +from hexdoc.graphics.validators import HexdocImage, ImageField, ItemImage, TagImage from hexdoc.model import HexdocModel, NoValue, TypeTaggedUnion from hexdoc.utils import listify diff --git a/src/hexdoc/minecraft/recipe/recipes.py b/src/hexdoc/minecraft/recipe/recipes.py index 166d77ce..358c37bb 100644 --- a/src/hexdoc/minecraft/recipe/recipes.py +++ b/src/hexdoc/minecraft/recipe/recipes.py @@ -11,6 +11,8 @@ from typing_extensions import override from hexdoc.core import ( + I18n, + LocalizedStr, ModResourceLoader, ResourceLocation, ValueIfVersion, @@ -20,7 +22,6 @@ from hexdoc.model import ResourceModel, TypeTaggedTemplate from hexdoc.utils import Inherit, InheritType, classproperty -from ..i18n import I18n, LocalizedStr from .ingredients import ItemIngredient, ItemIngredientList, ItemResult diff --git a/src/hexdoc/patchouli/book.py b/src/hexdoc/patchouli/book.py index d650f592..40d32db3 100644 --- a/src/hexdoc/patchouli/book.py +++ b/src/hexdoc/patchouli/book.py @@ -5,12 +5,12 @@ from hexdoc.core import ( ItemStack, + LocalizedStr, ModResourceLoader, ResLoc, ResourceLocation, ) from hexdoc.core.compat import AtLeast_1_20, Before_1_20 -from hexdoc.minecraft import LocalizedStr from hexdoc.model import Color, HexdocModel from hexdoc.utils import ContextSource, cast_context, sorted_dict diff --git a/src/hexdoc/patchouli/category.py b/src/hexdoc/patchouli/category.py index baa5362b..f35edf62 100644 --- a/src/hexdoc/patchouli/category.py +++ b/src/hexdoc/patchouli/category.py @@ -3,10 +3,9 @@ from pydantic import Field from pydantic.json_schema import SkipJsonSchema -from hexdoc.core import ResourceLocation +from hexdoc.core import LocalizedStr, ResourceLocation from hexdoc.core.loader import ModResourceLoader from hexdoc.graphics import ImageField, ItemImage, TextureImage -from hexdoc.minecraft import LocalizedStr from hexdoc.model import IDModel from hexdoc.utils import Sortable, sorted_dict from hexdoc.utils.graphs import TypedDiGraph diff --git a/src/hexdoc/patchouli/entry.py b/src/hexdoc/patchouli/entry.py index 5aaeca33..ca5910f4 100644 --- a/src/hexdoc/patchouli/entry.py +++ b/src/hexdoc/patchouli/entry.py @@ -2,9 +2,8 @@ from pydantic import Field -from hexdoc.core import ItemStack, ResourceLocation +from hexdoc.core import ItemStack, LocalizedStr, ResourceLocation from hexdoc.graphics import ImageField, ItemImage, TextureImage -from hexdoc.minecraft import LocalizedStr from hexdoc.minecraft.recipe import CraftingRecipe from hexdoc.model import Color, IDModel from hexdoc.utils import Sortable diff --git a/src/hexdoc/patchouli/page/abstract_pages.py b/src/hexdoc/patchouli/page/abstract_pages.py index 51318713..dcca327f 100644 --- a/src/hexdoc/patchouli/page/abstract_pages.py +++ b/src/hexdoc/patchouli/page/abstract_pages.py @@ -3,8 +3,7 @@ from pydantic import ConfigDict, model_validator from pydantic.functional_validators import ModelWrapValidatorHandler -from hexdoc.core import ResourceLocation -from hexdoc.minecraft import LocalizedStr +from hexdoc.core import LocalizedStr, ResourceLocation from hexdoc.minecraft.recipe import Recipe from hexdoc.model import TypeTaggedTemplate from hexdoc.utils import Inherit, InheritType, NoValue, classproperty diff --git a/src/hexdoc/patchouli/page/pages.py b/src/hexdoc/patchouli/page/pages.py index 29c7010d..8bb136f6 100644 --- a/src/hexdoc/patchouli/page/pages.py +++ b/src/hexdoc/patchouli/page/pages.py @@ -3,10 +3,9 @@ from pydantic import ValidationInfo, field_validator, model_validator -from hexdoc.core import Entity, ResourceLocation +from hexdoc.core import Entity, LocalizedStr, ResourceLocation from hexdoc.graphics import ImageField, ItemImage, TextureImage from hexdoc.graphics.validators import TagImage -from hexdoc.minecraft import LocalizedStr from hexdoc.minecraft.recipe import ( BlastingRecipe, CampfireCookingRecipe, diff --git a/src/hexdoc/patchouli/text.py b/src/hexdoc/patchouli/text.py index e33e23f1..623d0183 100644 --- a/src/hexdoc/patchouli/text.py +++ b/src/hexdoc/patchouli/text.py @@ -13,8 +13,7 @@ from pydantic.dataclasses import dataclass from pydantic.functional_validators import ModelWrapValidatorHandler -from hexdoc.core import Properties, ResourceLocation -from hexdoc.minecraft import I18n, LocalizedStr +from hexdoc.core import I18n, LocalizedStr, Properties, ResourceLocation from hexdoc.model import DEFAULT_CONFIG, HexdocModel, ValidationContextModel from hexdoc.plugin import PluginManager from hexdoc.utils import PydanticURL, TryGetEnum, classproperty diff --git a/src/hexdoc/plugin/manager.py b/src/hexdoc/plugin/manager.py index 4d6f43d4..3fba6ff9 100644 --- a/src/hexdoc/plugin/manager.py +++ b/src/hexdoc/plugin/manager.py @@ -28,9 +28,8 @@ from hexdoc.utils import ContextSource, ValidationContext if TYPE_CHECKING: - from hexdoc.core import Properties, ResourceLocation + from hexdoc.core import I18n, Properties, ResourceLocation from hexdoc.graphics.validators import ItemImage - from hexdoc.minecraft import I18n from hexdoc.patchouli import FormatTree from .book_plugin import BookPlugin diff --git a/src/hexdoc/plugin/specs.py b/src/hexdoc/plugin/specs.py index a836e3f5..8659f72a 100644 --- a/src/hexdoc/plugin/specs.py +++ b/src/hexdoc/plugin/specs.py @@ -12,8 +12,7 @@ from .types import HookReturn, HookReturns if TYPE_CHECKING: - from hexdoc.core import Properties, ResourceLocation - from hexdoc.minecraft import I18n + from hexdoc.core import I18n, Properties, ResourceLocation from hexdoc.patchouli import FormatTree HEXDOC_PROJECT_NAME = "hexdoc" diff --git a/src/hexdoc_modonomicon/book.py b/src/hexdoc_modonomicon/book.py index 7d3cffc0..9f1a6803 100644 --- a/src/hexdoc_modonomicon/book.py +++ b/src/hexdoc_modonomicon/book.py @@ -1,5 +1,4 @@ -from hexdoc.core import ResourceLocation -from hexdoc.minecraft import LocalizedStr +from hexdoc.core import LocalizedStr, ResourceLocation from hexdoc.model import HexdocModel from pydantic import Field, model_validator diff --git a/src/hexdoc_modonomicon/category.py b/src/hexdoc_modonomicon/category.py index ea7be980..9e7c748b 100644 --- a/src/hexdoc_modonomicon/category.py +++ b/src/hexdoc_modonomicon/category.py @@ -1,6 +1,5 @@ -from hexdoc.core import ResourceLocation +from hexdoc.core import LocalizedStr, ResourceLocation from hexdoc.graphics import ImageField, ItemImage, TextureImage -from hexdoc.minecraft import LocalizedStr from hexdoc.model import HexdocModel from pydantic import Field diff --git a/src/hexdoc_modonomicon/entry.py b/src/hexdoc_modonomicon/entry.py index 2134d942..11a0de43 100644 --- a/src/hexdoc_modonomicon/entry.py +++ b/src/hexdoc_modonomicon/entry.py @@ -1,6 +1,5 @@ -from hexdoc.core import ResourceLocation +from hexdoc.core import LocalizedStr, ResourceLocation from hexdoc.graphics import ImageField, ItemImage, TextureImage -from hexdoc.minecraft import LocalizedStr from hexdoc.model import HexdocModel from pydantic import Field diff --git a/submodules/HexMod b/submodules/HexMod index 458b7f39..2ce4cc3c 160000 --- a/submodules/HexMod +++ b/submodules/HexMod @@ -1 +1 @@ -Subproject commit 458b7f39a08679a8f24ea1e5fec28936629cb352 +Subproject commit 2ce4cc3c2c73891ffdd335b2c44e85284bfd58c6 diff --git a/test/integration/test_extend_book.py b/test/integration/test_extend_book.py index b2dc63c8..4ad7cd37 100644 --- a/test/integration/test_extend_book.py +++ b/test/integration/test_extend_book.py @@ -4,13 +4,12 @@ import pytest from hexdoc._hooks import HexdocPlugin from hexdoc.cli.utils.load import init_context -from hexdoc.core import ModResourceLoader, PathResourceDir, PluginResourceDir +from hexdoc.core import I18n, ModResourceLoader, PathResourceDir, PluginResourceDir from hexdoc.core.compat import MinecraftVersion from hexdoc.core.properties import EnvironmentVariableProps, Properties, TexturesProps from hexdoc.core.resource import ResourceLocation from hexdoc.graphics.loader import ImageLoader from hexdoc.graphics.renderer import ModelRenderer -from hexdoc.minecraft import I18n from hexdoc.patchouli.book import Book from hexdoc.patchouli.book_context import BookContext from hexdoc.patchouli.text import FormattingContext diff --git a/test/integration/test_modpack.py b/test/integration/test_modpack.py index 60c4a53d..9d706e18 100644 --- a/test/integration/test_modpack.py +++ b/test/integration/test_modpack.py @@ -4,13 +4,12 @@ import pytest from hexdoc._hooks import HexdocPlugin from hexdoc.cli.utils.load import init_context -from hexdoc.core import ModResourceLoader +from hexdoc.core import I18n, ModResourceLoader from hexdoc.core.compat import MinecraftVersion from hexdoc.core.properties import Properties from hexdoc.core.resource import ResourceLocation from hexdoc.graphics.loader import ImageLoader from hexdoc.graphics.renderer import ModelRenderer -from hexdoc.minecraft import I18n from hexdoc.patchouli.book import Book from hexdoc.patchouli.text import FormatTree from hexdoc.plugin import PluginManager diff --git a/test/minecraft/assets/test_with_texture.py b/test/minecraft/assets/test_with_texture.py index f94d4895..37cdf683 100644 --- a/test/minecraft/assets/test_with_texture.py +++ b/test/minecraft/assets/test_with_texture.py @@ -1,10 +1,9 @@ from typing import Any import pytest -from hexdoc.core import Properties +from hexdoc.core import I18n, Properties from hexdoc.core.properties import LangProps from hexdoc.graphics import ItemImage, TagImage -from hexdoc.minecraft.i18n import I18n from hexdoc.plugin import PluginManager from hexdoc.utils.context import ContextSource from pydantic import TypeAdapter diff --git a/test/minecraft/test_i18n.py b/test/minecraft/test_i18n.py index cad69b93..6e7c9230 100644 --- a/test/minecraft/test_i18n.py +++ b/test/minecraft/test_i18n.py @@ -1,9 +1,8 @@ from typing import Any import pytest -from hexdoc.core import ResourceLocation +from hexdoc.core import I18n, LocalizedStr, ResourceLocation from hexdoc.core.properties import LangProps -from hexdoc.minecraft import I18n, LocalizedStr from hexdoc.patchouli.page.abstract_pages import PageWithTitle from hexdoc.plugin import PluginManager diff --git a/test/patchouli/test_text.py b/test/patchouli/test_text.py index 0cd7de17..1fea2e58 100644 --- a/test/patchouli/test_text.py +++ b/test/patchouli/test_text.py @@ -3,8 +3,8 @@ from typing import Any, cast import pytest +from hexdoc.core import I18n from hexdoc.core.resource import ResourceLocation -from hexdoc.minecraft import I18n from hexdoc.patchouli.text import ( DEFAULT_MACROS, BookLink, From 70573202ea688d4dee63d3144f3ac1103dbe3398 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 13:07:58 -0400 Subject: [PATCH 068/106] Avoid swallowing errors when delegating to MissingImage in strict mode --- src/hexdoc/graphics/validators.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hexdoc/graphics/validators.py b/src/hexdoc/graphics/validators.py index 3fc7f144..3c47c048 100644 --- a/src/hexdoc/graphics/validators.py +++ b/src/hexdoc/graphics/validators.py @@ -58,6 +58,8 @@ def _validator( try: return handler(value) except ValidationError: + if MissingImage.should_raise(ResourceLocation.model_validate(value), info): + raise return MissingImage.model_validate(value, context=info.context) @@ -140,7 +142,7 @@ class MissingImage(TextureImage, annotation=None): @override @classmethod def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: - if Properties.of(context).textures.strict: + if cls.should_raise(id, context): raise ValueError(f"Failed to load image for id: {id}") logger.warning(f"Using missing texture for id: {id}") @@ -151,6 +153,10 @@ def load_id(cls, id: ResourceLocation, context: dict[str, Any]) -> Any: def _get_name(self, info: ValidationInfo): return LocalizedStr.with_value(str(self.id)) + @classmethod + def should_raise(cls, id: ResourceLocation, context: ContextSource): + return Properties.of(context).textures.strict + class ItemImage(HexdocImage, InlineItemModel, UnionModel, ABC): item: ItemStack From e61961484b09bb0449ba7c29215bb1eb4f965911 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 14:08:00 -0400 Subject: [PATCH 069/106] Truncate very long values in isinstance_or_raise --- src/hexdoc/utils/deserialize/assertions.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hexdoc/utils/deserialize/assertions.py b/src/hexdoc/utils/deserialize/assertions.py index 1738f1d7..0c79c905 100644 --- a/src/hexdoc/utils/deserialize/assertions.py +++ b/src/hexdoc/utils/deserialize/assertions.py @@ -25,14 +25,20 @@ def isinstance_or_raise( ungenericed_classes = tuple(get_origin(t) or t for t in class_or_tuple) if not isinstance(val, ungenericed_classes): - # just in case the caller messed up the message formatting + level = logger.getEffectiveLevel() + + # truncate absurdly long values + str_val = str(val) + if len(str_val) > 5000 and level >= logging.DEBUG: + str_val = str_val[:5000] + " [...truncated]" + subs = { "expected": list(class_or_tuple), "actual": type(val), - "value": val, + "value": str_val, } - if logger.getEffectiveLevel() >= logging.WARNING: + if level >= logging.WARNING: default_message = _DEFAULT_MESSAGE_SHORT else: default_message = _DEFAULT_MESSAGE_LONG @@ -40,6 +46,7 @@ def isinstance_or_raise( if message is None: raise TypeError(default_message.format(**subs)) + # just in case the caller messed up the message formatting try: raise TypeError(message.format(**subs)) except KeyError: From fb2b0bd0b27237a049a29cae9aa84111881e2c76 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 14:08:21 -0400 Subject: [PATCH 070/106] Fix type error when Jinja context is used as validation context --- src/hexdoc/utils/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hexdoc/utils/context.py b/src/hexdoc/utils/context.py index 3fe7c9a4..59b2e1cf 100644 --- a/src/hexdoc/utils/context.py +++ b/src/hexdoc/utils/context.py @@ -34,7 +34,7 @@ def of(cls, source: ContextSource, /) -> Self: case dict() | Context(): pass case _: - source = cast_or_raise(source.context, dict) + source = cast_or_raise(source.context, (dict, Context)) return cast_or_raise(source[cls.context_key], cls) def add_to_context(self, context: dict[str, Any], overwrite: bool = False): From cedd6088612ac4dd488b317e13582873f6693d7e Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 14:08:41 -0400 Subject: [PATCH 071/106] Use init_context in Jinja filters --- src/hexdoc/jinja/filters.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/hexdoc/jinja/filters.py b/src/hexdoc/jinja/filters.py index e1f8c40f..ec051a60 100644 --- a/src/hexdoc/jinja/filters.py +++ b/src/hexdoc/jinja/filters.py @@ -13,6 +13,7 @@ TextureImage, validate_image, ) +from hexdoc.model.base import init_context from hexdoc.patchouli import FormatTree from hexdoc.plugin import PluginManager @@ -20,6 +21,16 @@ _R = TypeVar("_R") +def hexdoc_pass_context(f: Callable[_P, _R]) -> Callable[_P, _R]: + @functools.wraps(f) + @pass_context + def wrapper(*args: _P.args, **kwargs: _P.kwargs): + with init_context(args[0]): + return f(*args, **kwargs) + + return wrapper + + def make_jinja_exceptions_suck_a_bit_less(f: Callable[_P, _R]) -> Callable[_P, _R]: @functools.wraps(f) def wrapper(*args: _P.args, **kwargs: _P.kwargs): @@ -82,14 +93,14 @@ def hexdoc_localize( # TODO: rename to hexdoc_texture_url -@pass_context +@hexdoc_pass_context @make_jinja_exceptions_suck_a_bit_less def hexdoc_texture(context: Context, id: str | ResourceLocation) -> str: image = validate_image(TextureImage, id, context) return str(image.url) -@pass_context +@hexdoc_pass_context @make_jinja_exceptions_suck_a_bit_less def hexdoc_item( context: Context, From 0d6653dc9fa0d7d5578f40c518e60d48c4cb4eb0 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 14:09:29 -0400 Subject: [PATCH 072/106] Set builtin parent as model attribute and only fail when actually rendering it --- src/hexdoc/graphics/model/__init__.py | 3 ++- src/hexdoc/graphics/model/block.py | 34 +++++++++++++++++---------- src/hexdoc/graphics/renderer.py | 16 ++++++++----- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/hexdoc/graphics/model/__init__.py b/src/hexdoc/graphics/model/__init__.py index 4a4c6d06..b52af2a8 100644 --- a/src/hexdoc/graphics/model/__init__.py +++ b/src/hexdoc/graphics/model/__init__.py @@ -4,6 +4,7 @@ "AnimationMeta", "BlockModel", "Blockstate", + "BuiltInModelType", "DisplayPosition", "Element", "ElementFace", @@ -12,7 +13,7 @@ ] from .animation import Animation, AnimationFrame, AnimationMeta -from .block import BlockModel +from .block import BlockModel, BuiltInModelType from .blockstate import Blockstate from .display import DisplayPosition from .element import Element, ElementFace, ElementFaceUV, FaceName diff --git a/src/hexdoc/graphics/model/block.py b/src/hexdoc/graphics/model/block.py index 55e62e5a..64a75e63 100644 --- a/src/hexdoc/graphics/model/block.py +++ b/src/hexdoc/graphics/model/block.py @@ -1,5 +1,6 @@ from __future__ import annotations +from enum import Enum from functools import cached_property from typing import Literal, Self @@ -78,7 +79,7 @@ class BlockModel(HexdocModel): """ # internal fields - _is_generated_item: bool = PrivateAttr(False) + _builtin_parent: BuiltInModelType | None = PrivateAttr(None) _id: ResourceLocation = PrivateAttr(None) @classmethod @@ -116,15 +117,12 @@ def resolve(self, loader: ModResourceLoader): ) loaded_parents.add(parent_id) - match parent_id: - case ResourceLocation("minecraft", "builtin/generated"): - self._is_generated_item = True - self.parent_id = None - case ResourceLocation("minecraft", "builtin/entity"): - raise ValueError(f"Unsupported model parent id: {parent_id}") - case _: - _, parent = self.load_only(loader, parent_id) - self._apply_parent(parent) + if builtin_parent := BuiltInModelType.get(parent_id): + self._builtin_parent = builtin_parent + self.parent_id = None + else: + _, parent = self.load_only(loader, parent_id) + self._apply_parent(parent) return self @@ -151,8 +149,8 @@ def is_resolved(self): return self.parent_id is None @property - def is_generated_item(self): - return self._is_generated_item + def builtin_parent(self): + return self._builtin_parent @property def id(self): @@ -191,3 +189,15 @@ class ItemOverride(HexdocModel): """The path to the model to use if the case is met.""" predicate: dict[ResourceLocation, float] """Item predicates that must be true for this model to be used.""" + + +class BuiltInModelType(Enum): + GENERATED = ResourceLocation("minecraft", "builtin/generated") + ENTITY = ResourceLocation("minecraft", "builtin/entity") + + @classmethod + def get(cls, id: ResourceLocation): + try: + return cls(id) + except ValueError: + return None diff --git a/src/hexdoc/graphics/renderer.py b/src/hexdoc/graphics/renderer.py index a1ed978c..6189ad7c 100644 --- a/src/hexdoc/graphics/renderer.py +++ b/src/hexdoc/graphics/renderer.py @@ -16,6 +16,7 @@ from hexdoc.core import ModResourceLoader, ResourceLocation from hexdoc.core.properties import AnimationFormat +from hexdoc.graphics.model.block import BuiltInModelType from .block import BlockRenderer from .model import BlockModel @@ -83,12 +84,15 @@ def render_model( model.resolve(self.loader) - if model.is_generated_item: - frames = self._render_item(model) - image_type = ImageType.ITEM - else: - frames = self._render_block(model) - image_type = ImageType.BLOCK + match model.builtin_parent: + case BuiltInModelType.GENERATED: + frames = self._render_item(model) + image_type = ImageType.ITEM + case None: + frames = self._render_block(model) + image_type = ImageType.BLOCK + case builtin_type: + raise ValueError(f"Unsupported model parent id: {builtin_type.value}") return self.save_image(output_path, frames), image_type From 704793dab165a75ea693cdb185005232029128a9 Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 14:09:54 -0400 Subject: [PATCH 073/106] Fix errors related to old texture system --- src/hexdoc/_hooks.py | 1 - .../recipes/minecraft/crafting_table.html.jinja | 3 ++- src/hexdoc/_templates/textures.jcss.jinja | 13 ------------- 3 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 src/hexdoc/_templates/textures.jcss.jinja diff --git a/src/hexdoc/_hooks.py b/src/hexdoc/_hooks.py index 875e80b0..a43ff5ab 100644 --- a/src/hexdoc/_hooks.py +++ b/src/hexdoc/_hooks.py @@ -83,7 +83,6 @@ def default_rendered_templates(self) -> dict[str | Path, str]: return { "index.html": "index.html.jinja", "index.css": "index.css.jinja", - "textures.css": "textures.jcss.jinja", "index.js": "index.js.jinja", } diff --git a/src/hexdoc/_templates/recipes/minecraft/crafting_table.html.jinja b/src/hexdoc/_templates/recipes/minecraft/crafting_table.html.jinja index 15d900a3..c39dc919 100644 --- a/src/hexdoc/_templates/recipes/minecraft/crafting_table.html.jinja +++ b/src/hexdoc/_templates/recipes/minecraft/crafting_table.html.jinja @@ -1,6 +1,7 @@ {% extends "recipes/base.html.jinja" %} {% import "macros/recipes.html.jinja" as recipe_macros with context %} +{% import "macros/images.html.jinja" as Images with context -%} {% block recipe_class -%} crafting-table @@ -20,6 +21,6 @@
- {{ texture_macros.render_item(recipe.result.item, count=recipe.result.count) }} + {{ Images.item(recipe.result.item, count=recipe.result.count) }}
{% endblock content %} diff --git a/src/hexdoc/_templates/textures.jcss.jinja b/src/hexdoc/_templates/textures.jcss.jinja deleted file mode 100644 index 48bc5876..00000000 --- a/src/hexdoc/_templates/textures.jcss.jinja +++ /dev/null @@ -1,13 +0,0 @@ -{% for animation in animations %} - .{{ animation.css_class }} { - animation: {{ animation.css_class }} {{ animation.time_seconds }}s linear infinite; - background-size: 100%; - background-image: url("{{ animation.url }}"); - } - - @keyframes {{ animation.css_class }} { - {% for frame in animation.frames %} - {{ frame.start_percent }}%, {{ frame.end_percent }}% { background-position-y: {{ -100 * frame.index }}% } - {% endfor %} - } -{% endfor %} From ba03d904bb030629f55899bd02241888e94caecc Mon Sep 17 00:00:00 2001 From: object-Object Date: Sat, 25 May 2024 14:20:38 -0400 Subject: [PATCH 074/106] Rename hexdoc_texture and hexdoc_item to hexdoc_texture_image and hexdoc_item_image --- src/hexdoc/_templates/macros/images.html.jinja | 7 +++++++ .../pages/patchouli/multiblock.html.jinja | 5 +---- .../pages/patchouli/spotlight.html.jinja | 5 +---- .../recipes/minecraft/furnace.html.jinja | 2 +- src/hexdoc/jinja/__init__.py | 11 ++++++++--- src/hexdoc/jinja/filters.py | 18 ++++-------------- src/hexdoc/jinja/render.py | 8 ++++---- submodules/HexMod | 2 +- 8 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/hexdoc/_templates/macros/images.html.jinja b/src/hexdoc/_templates/macros/images.html.jinja index 55293bda..7fa16a66 100644 --- a/src/hexdoc/_templates/macros/images.html.jinja +++ b/src/hexdoc/_templates/macros/images.html.jinja @@ -23,3 +23,10 @@ {% macro url(image) -%} {{ site_url }}/{{ image.first_url }} {%- endmacro %} + +{% macro load_texture(id, alt) -%} + {{ alt }} +{%- endmacro %} diff --git a/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja b/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja index 336f4bf3..6bfd9aa7 100644 --- a/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja +++ b/src/hexdoc/_templates/pages/patchouli/multiblock.html.jinja @@ -12,10 +12,7 @@ {% for item, count in page.multiblock.bill_of_materials() %}
- Spotlight inventory slot + {{ Images.load_texture("hexdoc:textures/gui/spotlight.png", "Spotlight inventory slot") }} {{ Images.item(item) }}
{{ count }}x {{ item.name }} diff --git a/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja b/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja index 43a5e6eb..e19f9cd7 100644 --- a/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja +++ b/src/hexdoc/_templates/pages/patchouli/spotlight.html.jinja @@ -4,10 +4,7 @@ {% block inner_body %}
- Spotlight inventory slot + {{ Images.load_texture("hexdoc:textures/gui/spotlight.png", "Spotlight inventory slot") }} {{ Images.item(page.item) }}
{{ super() }} diff --git a/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja b/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja index f4b102b9..b8877581 100644 --- a/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja +++ b/src/hexdoc/_templates/recipes/minecraft/furnace.html.jinja @@ -39,7 +39,7 @@ {# TODO: move somewhere more sensible #} {% macro extra_info(item_id, text, classes="") -%}
- {{ Images.item(item_id|hexdoc_item)}} + {{ Images.item(item_id|hexdoc_item_image)}} {{ text }}
{%- endmacro %} diff --git a/src/hexdoc/jinja/__init__.py b/src/hexdoc/jinja/__init__.py index df5d87bb..8724cc38 100644 --- a/src/hexdoc/jinja/__init__.py +++ b/src/hexdoc/jinja/__init__.py @@ -1,10 +1,15 @@ __all__ = [ "IncludeRawExtension", - "hexdoc_item", + "hexdoc_item_image", "hexdoc_localize", - "hexdoc_texture", + "hexdoc_texture_image", "hexdoc_wrap", ] from .extensions import IncludeRawExtension -from .filters import hexdoc_item, hexdoc_localize, hexdoc_texture, hexdoc_wrap +from .filters import ( + hexdoc_item_image, + hexdoc_localize, + hexdoc_texture_image, + hexdoc_wrap, +) diff --git a/src/hexdoc/jinja/filters.py b/src/hexdoc/jinja/filters.py index ec051a60..de226e42 100644 --- a/src/hexdoc/jinja/filters.py +++ b/src/hexdoc/jinja/filters.py @@ -7,12 +7,7 @@ from hexdoc.core import I18n, Properties, ResourceLocation from hexdoc.core.resource import ItemStack -from hexdoc.graphics.validators import ( - ItemImage, - MissingImage, - TextureImage, - validate_image, -) +from hexdoc.graphics.validators import ItemImage, TextureImage, validate_image from hexdoc.model.base import init_context from hexdoc.patchouli import FormatTree from hexdoc.plugin import PluginManager @@ -92,18 +87,13 @@ def hexdoc_localize( return formatted -# TODO: rename to hexdoc_texture_url @hexdoc_pass_context @make_jinja_exceptions_suck_a_bit_less -def hexdoc_texture(context: Context, id: str | ResourceLocation) -> str: - image = validate_image(TextureImage, id, context) - return str(image.url) +def hexdoc_texture_image(context: Context, id: str | ResourceLocation): + return validate_image(TextureImage, id, context) @hexdoc_pass_context @make_jinja_exceptions_suck_a_bit_less -def hexdoc_item( - context: Context, - id: str | ResourceLocation | ItemStack, -) -> ItemImage | MissingImage: +def hexdoc_item_image(context: Context, id: str | ResourceLocation | ItemStack): return validate_image(ItemImage, id, context) diff --git a/src/hexdoc/jinja/render.py b/src/hexdoc/jinja/render.py index 8adbbb88..6d0c2308 100644 --- a/src/hexdoc/jinja/render.py +++ b/src/hexdoc/jinja/render.py @@ -26,9 +26,9 @@ from .extensions import DefaultMacroExtension, IncludeRawExtension from .filters import ( - hexdoc_item, + hexdoc_item_image, hexdoc_localize, - hexdoc_texture, + hexdoc_texture_image, hexdoc_wrap, ) @@ -105,8 +105,8 @@ def create_jinja_env_with_loader(loader: BaseLoader): env.filters |= { # pyright: ignore[reportAttributeAccessIssue] "hexdoc_wrap": hexdoc_wrap, "hexdoc_localize": hexdoc_localize, - "hexdoc_texture": hexdoc_texture, - "hexdoc_item": hexdoc_item, + "hexdoc_texture_image": hexdoc_texture_image, + "hexdoc_item_image": hexdoc_item_image, } return env diff --git a/submodules/HexMod b/submodules/HexMod index 2ce4cc3c..98d176ed 160000 --- a/submodules/HexMod +++ b/submodules/HexMod @@ -1 +1 @@ -Subproject commit 2ce4cc3c2c73891ffdd335b2c44e85284bfd58c6 +Subproject commit 98d176ed85216718b7fe1f07c42279f9f5841eb1 From dd5c6a33815a65d5bc16d3fb322f34617b30e8f5 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 29 May 2024 12:43:50 -0400 Subject: [PATCH 075/106] Fix new Pyright errors --- src/hexdoc/core/loader.py | 2 +- src/hexdoc/utils/deserialize/assertions.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hexdoc/core/loader.py b/src/hexdoc/core/loader.py index 011a8f8e..7deb8f81 100644 --- a/src/hexdoc/core/loader.py +++ b/src/hexdoc/core/loader.py @@ -515,7 +515,7 @@ def export( cache: bool = False, ) -> None: ... - def export( + def export( # pyright: ignore[reportInconsistentOverload] self, path: Path, data: str | bytes, diff --git a/src/hexdoc/utils/deserialize/assertions.py b/src/hexdoc/utils/deserialize/assertions.py index 0c79c905..d443e6b1 100644 --- a/src/hexdoc/utils/deserialize/assertions.py +++ b/src/hexdoc/utils/deserialize/assertions.py @@ -32,7 +32,7 @@ def isinstance_or_raise( if len(str_val) > 5000 and level >= logging.DEBUG: str_val = str_val[:5000] + " [...truncated]" - subs = { + subs: dict[str, Any] = { "expected": list(class_or_tuple), "actual": type(val), "value": str_val, From 16ae3b0ac94427733dcd15d2861b432917fc7cdc Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 29 May 2024 12:49:29 -0400 Subject: [PATCH 076/106] Fix pytest errors --- test/integration/test_extend_book.py | 4 ++-- test/integration/test_modpack.py | 2 +- test/patchouli/test_text.py | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/test/integration/test_extend_book.py b/test/integration/test_extend_book.py index 4ad7cd37..83132bee 100644 --- a/test/integration/test_extend_book.py +++ b/test/integration/test_extend_book.py @@ -76,7 +76,7 @@ def parent_props(tmp_path: Path): PluginResourceDir(modid="hexdoc"), ], textures=TexturesProps( - missing=set([ResourceLocation("minecraft", "stone")]), + strict=False, ), default_branch="", env=EnvironmentVariableProps( @@ -127,7 +127,7 @@ def child_props(tmp_path: Path, parent_props: Properties): PluginResourceDir(modid="hexdoc"), ], textures=TexturesProps( - missing=set([ResourceLocation("minecraft", "stone")]), + strict=False, ), default_branch="", env=EnvironmentVariableProps( diff --git a/test/integration/test_modpack.py b/test/integration/test_modpack.py index 9d706e18..fef9ceb8 100644 --- a/test/integration/test_modpack.py +++ b/test/integration/test_modpack.py @@ -72,7 +72,7 @@ def props(tmp_path: Path): {"modid": "hexdoc"}, ], "textures": { - "missing": ["minecraft:stone"], + "strict": False, }, }, ) diff --git a/test/patchouli/test_text.py b/test/patchouli/test_text.py index 1fea2e58..c1bcd551 100644 --- a/test/patchouli/test_text.py +++ b/test/patchouli/test_text.py @@ -5,6 +5,7 @@ import pytest from hexdoc.core import I18n from hexdoc.core.resource import ResourceLocation +from hexdoc.jinja.render import create_jinja_env_with_loader from hexdoc.patchouli.text import ( DEFAULT_MACROS, BookLink, @@ -16,7 +17,7 @@ SpecialStyleType, ) from hexdoc.plugin import PluginManager -from jinja2 import Environment, PackageLoader +from jinja2 import PackageLoader from yarl import URL @@ -47,7 +48,7 @@ def flatten_html(html: str): def hexdoc_block(value: FormatTree): loader = PackageLoader("hexdoc", "_templates") - env = Environment(loader=loader) + env = create_jinja_env_with_loader(loader) template = env.from_string( """\ {%- import "macros/formatting.html.jinja" as fmt with context -%} From 62040dee99b2f2ac57895f42bd35690c2dc3823b Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 29 May 2024 13:05:39 -0400 Subject: [PATCH 077/106] Bump version to rc1.dev0 to support new hexdoc-minecraft in tests --- src/hexdoc/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hexdoc/__version__.py b/src/hexdoc/__version__.py index f7549890..30ccc935 100644 --- a/src/hexdoc/__version__.py +++ b/src/hexdoc/__version__.py @@ -1 +1 @@ -VERSION = "1!0.1.0a17" +VERSION = "1!0.1.0rc1.dev0" From be8e7dd50ec97ad060539e5ad5381619221e1129 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 29 May 2024 13:37:05 -0400 Subject: [PATCH 078/106] Add --no-clean-exports flag for hexdoc-minecraft --- src/hexdoc/cli/app.py | 5 ++++- src/hexdoc/cli/ci.py | 2 ++ src/hexdoc/core/loader.py | 34 ++++++++++++++++------------------ 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/hexdoc/cli/app.py b/src/hexdoc/cli/app.py index 96b8c5fb..cf22d92d 100644 --- a/src/hexdoc/cli/app.py +++ b/src/hexdoc/cli/app.py @@ -186,6 +186,7 @@ def build( branch: BranchOption, release: ReleaseOption = False, clean: bool = False, + clean_exports: bool = True, props_file: PropsOption, ) -> Path: """Export resources and render the web book. @@ -200,7 +201,9 @@ def build( logger.info("Exporting resources.") with ( - ModResourceLoader.clean_and_load_all(props, pm, export=True) as loader, + ModResourceLoader.load_all( + props, pm, export=True, clean=clean_exports + ) as loader, ModelRenderer(loader=loader) as renderer, ): site_path = plugin.site_path(versioned=release) diff --git a/src/hexdoc/cli/ci.py b/src/hexdoc/cli/ci.py index a31b62bf..1e3aac50 100644 --- a/src/hexdoc/cli/ci.py +++ b/src/hexdoc/cli/ci.py @@ -28,6 +28,7 @@ def build( *, props_file: PropsOption, release: ReleaseOption, + clean_exports: bool = True, ): from . import app as hexdoc_app @@ -52,6 +53,7 @@ def build( branch=env.branch, props_file=props_file, release=release, + clean_exports=clean_exports, ) site_dist = site_path / "dist" diff --git a/src/hexdoc/core/loader.py b/src/hexdoc/core/loader.py index 7deb8f81..61fed593 100644 --- a/src/hexdoc/core/loader.py +++ b/src/hexdoc/core/loader.py @@ -59,12 +59,24 @@ def clean_and_load_all( *, export: bool = False, ): + return cls.load_all(props, pm, export=export, clean=True) + + @classmethod + def load_all( + cls, + props: Properties, + pm: PluginManager, + *, + export: bool = False, + clean: bool = False, + ) -> Self: # clear the export dir so we start with a clean slate if props.export_dir and export: - subprocess.run( - ["git", "clean", "-fdX", props.export_dir], - cwd=props.props_dir, - ) + if clean: + subprocess.run( + ["git", "clean", "-fdX", props.export_dir], + cwd=props.props_dir, + ) write_to_path( props.export_dir / "__init__.py", @@ -76,20 +88,6 @@ def clean_and_load_all( ), ) - return cls.load_all( - props, - pm, - export=export, - ) - - @classmethod - def load_all( - cls, - props: Properties, - pm: PluginManager, - *, - export: bool = False, - ) -> Self: export_dir = props.export_dir if export else None stack = ExitStack() From ffdca8f0cd037499ac19c1c24dacd41ae66b112c Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 29 May 2024 14:26:27 -0400 Subject: [PATCH 079/106] Add missing whitespace control to image macros --- src/hexdoc/_templates/macros/images.html.jinja | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hexdoc/_templates/macros/images.html.jinja b/src/hexdoc/_templates/macros/images.html.jinja index 7fa16a66..adb4b35d 100644 --- a/src/hexdoc/_templates/macros/images.html.jinja +++ b/src/hexdoc/_templates/macros/images.html.jinja @@ -1,27 +1,27 @@ {% macro image(image, name=none, class_names=[], lazy=true, title=true, is_first=none) -%} - {% with name = name if name is not none else image.name %} - {% include image.template~".html.jinja" %} - {% endwith %} + {%- with name = name if name is not none else image.name -%} + {%- include image.template~".html.jinja" -%} + {%- endwith -%} {%- endmacro %} {% macro item(item, is_first=none, count=1) -%} - {{ image(item, is_first=is_first, class_names=["item-texture"]) }} - {% if count > 1 -%} + {{- image(item, is_first=is_first, class_names=["item-texture"]) -}} + {%- if count > 1 -%}
{{ count }}
- {%- endif %} + {%- endif -%} {%- endmacro %} {% macro recipe_gui(recipe, class_names=[]) -%} - {{ image( + {{- image( recipe.gui_texture, name=recipe.gui_name, class_names=class_names, lazy=false, - ) }} + ) -}} {%- endmacro %} {% macro url(image) -%} - {{ site_url }}/{{ image.first_url }} + {{- site_url }}/{{ image.first_url -}} {%- endmacro %} {% macro load_texture(id, alt) -%} From 018a94fca2691d847ea917b306dc685036a0fd95 Mon Sep 17 00:00:00 2001 From: object-Object Date: Wed, 29 May 2024 14:44:27 -0400 Subject: [PATCH 080/106] Update snapshots with new image rendering --- submodules/HexMod | 2 +- .../__snapshots__/test_copier.ambr | 233 +- ...test_index[vlatestmainen_usindex.html].raw | 96 +- .../__snapshots__/test_main_1.19.ambr | 452 +- ...test_files[vlatestmainen_usindex.html].raw | 11410 +++++++------- .../__snapshots__/test_main_main.ambr | 486 +- ...test_files[vlatestmainen_usindex.html].raw | 12906 ++++++++-------- test/integration/test_main.py | 12 +- 8 files changed, 13280 insertions(+), 12317 deletions(-) diff --git a/submodules/HexMod b/submodules/HexMod index 98d176ed..e84a1b58 160000 --- a/submodules/HexMod +++ b/submodules/HexMod @@ -1 +1 @@ -Subproject commit 98d176ed85216718b7fe1f07c42279f9f5841eb1 +Subproject commit e84a1b58afdf4bc53f7f458149789926e33a1bea diff --git a/test/integration/__snapshots__/test_copier.ambr b/test/integration/__snapshots__/test_copier.ambr index 1cfd5332..8f600929 100644 --- a/test/integration/__snapshots__/test_copier.ambr +++ b/test/integration/__snapshots__/test_copier.ambr @@ -60,6 +60,237 @@ 'v/latest/main/en_us/patterns/index.html', 'v/latest/main/en_us/patterns/spells', 'v/latest/main/en_us/patterns/spells/index.html', - 'v/latest/main/en_us/textures.css', + 'v/latest/main/renders', + 'v/latest/main/renders/farmersdelight', + 'v/latest/main/renders/farmersdelight/item', + 'v/latest/main/renders/farmersdelight/item/skillet.png', + 'v/latest/main/renders/hexcasting', + 'v/latest/main/renders/hexcasting/block', + 'v/latest/main/renders/hexcasting/block/quenched_allay_0.png', + 'v/latest/main/renders/hexcasting/item', + 'v/latest/main/renders/hexcasting/item/abacus.png', + 'v/latest/main/renders/hexcasting/item/akashic_bookshelf.png', + 'v/latest/main/renders/hexcasting/item/akashic_connector.png', + 'v/latest/main/renders/hexcasting/item/akashic_record.png', + 'v/latest/main/renders/hexcasting/item/amethyst_dust.png', + 'v/latest/main/renders/hexcasting/item/amethyst_dust_block.png', + 'v/latest/main/renders/hexcasting/item/amethyst_sconce.png', + 'v/latest/main/renders/hexcasting/item/amethyst_tiles.png', + 'v/latest/main/renders/hexcasting/item/ancient_scroll_paper.png', + 'v/latest/main/renders/hexcasting/item/ancient_scroll_paper_lantern.png', + 'v/latest/main/renders/hexcasting/item/artifact.png', + 'v/latest/main/renders/hexcasting/item/charged_amethyst.png', + 'v/latest/main/renders/hexcasting/item/cypher.png', + 'v/latest/main/renders/hexcasting/item/default_colorizer.gif', + 'v/latest/main/renders/hexcasting/item/directrix', + 'v/latest/main/renders/hexcasting/item/directrix/boolean.png', + 'v/latest/main/renders/hexcasting/item/directrix/empty.png', + 'v/latest/main/renders/hexcasting/item/directrix/redstone.png', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_blue.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_brown.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_cyan.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_gray.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_green.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_light_blue.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_light_gray.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_lime.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_magenta.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_orange.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_pink.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_purple.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_red.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_white.gif', + 'v/latest/main/renders/hexcasting/item/dye_colorizer_yellow.gif', + 'v/latest/main/renders/hexcasting/item/edified_button.png', + 'v/latest/main/renders/hexcasting/item/edified_door.png', + 'v/latest/main/renders/hexcasting/item/edified_log.png', + 'v/latest/main/renders/hexcasting/item/edified_log_amethyst.png', + 'v/latest/main/renders/hexcasting/item/edified_log_aventurine.png', + 'v/latest/main/renders/hexcasting/item/edified_log_citrine.png', + 'v/latest/main/renders/hexcasting/item/edified_log_purple.png', + 'v/latest/main/renders/hexcasting/item/edified_panel.png', + 'v/latest/main/renders/hexcasting/item/edified_planks.png', + 'v/latest/main/renders/hexcasting/item/edified_pressure_plate.png', + 'v/latest/main/renders/hexcasting/item/edified_slab.png', + 'v/latest/main/renders/hexcasting/item/edified_stairs.png', + 'v/latest/main/renders/hexcasting/item/edified_tile.png', + 'v/latest/main/renders/hexcasting/item/edified_trapdoor.png', + 'v/latest/main/renders/hexcasting/item/edified_wood.png', + 'v/latest/main/renders/hexcasting/item/focus.png', + 'v/latest/main/renders/hexcasting/item/impetus', + 'v/latest/main/renders/hexcasting/item/impetus/empty.png', + 'v/latest/main/renders/hexcasting/item/impetus/look.png', + 'v/latest/main/renders/hexcasting/item/impetus/redstone.png', + 'v/latest/main/renders/hexcasting/item/impetus/rightclick.png', + 'v/latest/main/renders/hexcasting/item/jeweler_hammer.png', + 'v/latest/main/renders/hexcasting/item/lens.png', + 'v/latest/main/renders/hexcasting/item/lore_fragment.png', + 'v/latest/main/renders/hexcasting/item/phial_small_0.png', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_agender.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_aroace.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_aromantic.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_asexual.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_bisexual.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_demiboy.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_demigirl.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_gay.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_genderfluid.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_genderqueer.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_intersex.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_lesbian.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_nonbinary.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_pansexual.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_plural.gif', + 'v/latest/main/renders/hexcasting/item/pride_colorizer_transgender.gif', + 'v/latest/main/renders/hexcasting/item/quenched_shard_0.png', + 'v/latest/main/renders/hexcasting/item/scroll_paper.png', + 'v/latest/main/renders/hexcasting/item/scroll_paper_lantern.png', + 'v/latest/main/renders/hexcasting/item/scroll_pristine_large.png', + 'v/latest/main/renders/hexcasting/item/scroll_pristine_medium.png', + 'v/latest/main/renders/hexcasting/item/scroll_pristine_small.png', + 'v/latest/main/renders/hexcasting/item/slate_blank.png', + 'v/latest/main/renders/hexcasting/item/slate_block.png', + 'v/latest/main/renders/hexcasting/item/spellbook.png', + 'v/latest/main/renders/hexcasting/item/staff', + 'v/latest/main/renders/hexcasting/item/staff/acacia.png', + 'v/latest/main/renders/hexcasting/item/staff/birch.png', + 'v/latest/main/renders/hexcasting/item/staff/crimson.png', + 'v/latest/main/renders/hexcasting/item/staff/dark_oak.png', + 'v/latest/main/renders/hexcasting/item/staff/edified.png', + 'v/latest/main/renders/hexcasting/item/staff/jungle.png', + 'v/latest/main/renders/hexcasting/item/staff/mangrove.png', + 'v/latest/main/renders/hexcasting/item/staff/mindsplice.png', + 'v/latest/main/renders/hexcasting/item/staff/oak.png', + 'v/latest/main/renders/hexcasting/item/staff/quenched_0.png', + 'v/latest/main/renders/hexcasting/item/staff/spruce.png', + 'v/latest/main/renders/hexcasting/item/staff/warped.png', + 'v/latest/main/renders/hexcasting/item/stripped_edified_log.png', + 'v/latest/main/renders/hexcasting/item/stripped_edified_wood.png', + 'v/latest/main/renders/hexcasting/item/thought_knot.png', + 'v/latest/main/renders/hexcasting/item/trinket.png', + 'v/latest/main/renders/hexcasting/item/uuid_colorizer.gif', + 'v/latest/main/renders/hexcasting/textures', + 'v/latest/main/renders/hexcasting/textures/gui', + 'v/latest/main/renders/hexcasting/textures/gui/entries', + 'v/latest/main/renders/hexcasting/textures/gui/entries/spell_circle.png', + 'v/latest/main/renders/hexdoc', + 'v/latest/main/renders/hexdoc/textures', + 'v/latest/main/renders/hexdoc/textures/item', + 'v/latest/main/renders/hexdoc/textures/item/tag.png', + 'v/latest/main/renders/minecraft', + 'v/latest/main/renders/minecraft/item', + 'v/latest/main/renders/minecraft/item/acacia_planks.png', + 'v/latest/main/renders/minecraft/item/amethyst_block.png', + 'v/latest/main/renders/minecraft/item/amethyst_shard.png', + 'v/latest/main/renders/minecraft/item/arrow.png', + 'v/latest/main/renders/minecraft/item/azalea.png', + 'v/latest/main/renders/minecraft/item/beacon.png', + 'v/latest/main/renders/minecraft/item/bedrock.png', + 'v/latest/main/renders/minecraft/item/birch_planks.png', + 'v/latest/main/renders/minecraft/item/blaze_rod.png', + 'v/latest/main/renders/minecraft/item/blue_dye.png', + 'v/latest/main/renders/minecraft/item/book.png', + 'v/latest/main/renders/minecraft/item/bookshelf.png', + 'v/latest/main/renders/minecraft/item/bread.png', + 'v/latest/main/renders/minecraft/item/brown_dye.png', + 'v/latest/main/renders/minecraft/item/budding_amethyst.png', + 'v/latest/main/renders/minecraft/item/bundle.png', + 'v/latest/main/renders/minecraft/item/carrot.png', + 'v/latest/main/renders/minecraft/item/chain.png', + 'v/latest/main/renders/minecraft/item/chorus_fruit.png', + 'v/latest/main/renders/minecraft/item/cobblestone.png', + 'v/latest/main/renders/minecraft/item/comparator.png', + 'v/latest/main/renders/minecraft/item/copper_ingot.png', + 'v/latest/main/renders/minecraft/item/crimson_planks.png', + 'v/latest/main/renders/minecraft/item/cyan_dye.png', + 'v/latest/main/renders/minecraft/item/dark_oak_planks.png', + 'v/latest/main/renders/minecraft/item/deepslate.png', + 'v/latest/main/renders/minecraft/item/egg.png', + 'v/latest/main/renders/minecraft/item/elytra.png', + 'v/latest/main/renders/minecraft/item/emerald.png', + 'v/latest/main/renders/minecraft/item/ender_pearl.png', + 'v/latest/main/renders/minecraft/item/feather.png', + 'v/latest/main/renders/minecraft/item/flint_and_steel.png', + 'v/latest/main/renders/minecraft/item/glass.png', + 'v/latest/main/renders/minecraft/item/glass_bottle.png', + 'v/latest/main/renders/minecraft/item/glowstone_dust.png', + 'v/latest/main/renders/minecraft/item/gold_ingot.png', + 'v/latest/main/renders/minecraft/item/gold_nugget.png', + 'v/latest/main/renders/minecraft/item/gray_dye.png', + 'v/latest/main/renders/minecraft/item/green_dye.png', + 'v/latest/main/renders/minecraft/item/honeycomb.png', + 'v/latest/main/renders/minecraft/item/iron_bars.png', + 'v/latest/main/renders/minecraft/item/iron_ingot.png', + 'v/latest/main/renders/minecraft/item/iron_nugget.png', + 'v/latest/main/renders/minecraft/item/item_frame.png', + 'v/latest/main/renders/minecraft/item/jungle_planks.png', + 'v/latest/main/renders/minecraft/item/knowledge_book.png', + 'v/latest/main/renders/minecraft/item/lava_bucket.png', + 'v/latest/main/renders/minecraft/item/leather.png', + 'v/latest/main/renders/minecraft/item/light_blue_dye.png', + 'v/latest/main/renders/minecraft/item/light_gray_dye.png', + 'v/latest/main/renders/minecraft/item/lime_dye.png', + 'v/latest/main/renders/minecraft/item/lodestone.png', + 'v/latest/main/renders/minecraft/item/magenta_dye.png', + 'v/latest/main/renders/minecraft/item/mangrove_planks.png', + 'v/latest/main/renders/minecraft/item/moss_block.png', + 'v/latest/main/renders/minecraft/item/music_disc_11.png', + 'v/latest/main/renders/minecraft/item/name_tag.png', + 'v/latest/main/renders/minecraft/item/nether_star.png', + 'v/latest/main/renders/minecraft/item/oak_planks.png', + 'v/latest/main/renders/minecraft/item/oak_sign.png', + 'v/latest/main/renders/minecraft/item/observer.png', + 'v/latest/main/renders/minecraft/item/orange_dye.png', + 'v/latest/main/renders/minecraft/item/paper.png', + 'v/latest/main/renders/minecraft/item/pig_spawn_egg.png', + 'v/latest/main/renders/minecraft/item/pink_dye.png', + 'v/latest/main/renders/minecraft/item/piston.png', + 'v/latest/main/renders/minecraft/item/potion.png', + 'v/latest/main/renders/minecraft/item/purple_candle.png', + 'v/latest/main/renders/minecraft/item/purple_dye.png', + 'v/latest/main/renders/minecraft/item/purpur_block.png', + 'v/latest/main/renders/minecraft/item/quartz.png', + 'v/latest/main/renders/minecraft/item/raw_copper.png', + 'v/latest/main/renders/minecraft/item/raw_iron.png', + 'v/latest/main/renders/minecraft/item/red_dye.png', + 'v/latest/main/renders/minecraft/item/red_mushroom.png', + 'v/latest/main/renders/minecraft/item/repeater.png', + 'v/latest/main/renders/minecraft/item/shulker_box.png', + 'v/latest/main/renders/minecraft/item/skeleton_skull.png', + 'v/latest/main/renders/minecraft/item/spruce_planks.png', + 'v/latest/main/renders/minecraft/item/spyglass.png', + 'v/latest/main/renders/minecraft/item/stick.png', + 'v/latest/main/renders/minecraft/item/stone_brick_wall.png', + 'v/latest/main/renders/minecraft/item/string.png', + 'v/latest/main/renders/minecraft/item/torch.png', + 'v/latest/main/renders/minecraft/item/warped_planks.png', + 'v/latest/main/renders/minecraft/item/water_bucket.png', + 'v/latest/main/renders/minecraft/item/wheat.png', + 'v/latest/main/renders/minecraft/item/wheat_seeds.png', + 'v/latest/main/renders/minecraft/item/white_dye.png', + 'v/latest/main/renders/minecraft/item/wither_skeleton_skull.png', + 'v/latest/main/renders/minecraft/item/wooden_pickaxe.png', + 'v/latest/main/renders/minecraft/item/writable_book.png', + 'v/latest/main/renders/minecraft/item/yellow_dye.png', + 'v/latest/main/renders/minecraft/textures', + 'v/latest/main/renders/minecraft/textures/entities', + 'v/latest/main/renders/minecraft/textures/entities/allay.png', + 'v/latest/main/renders/minecraft/textures/entities/villagers', + 'v/latest/main/renders/minecraft/textures/entities/villagers/cleric.png', + 'v/latest/main/renders/minecraft/textures/entities/villagers/librarian.png', + 'v/latest/main/renders/minecraft/textures/entities/villagers/mason.png', + 'v/latest/main/renders/minecraft/textures/entities/villagers/none.png', + 'v/latest/main/renders/minecraft/textures/entities/villagers/toolsmith.png', + 'v/latest/main/renders/minecraft/textures/gui', + 'v/latest/main/renders/minecraft/textures/gui/hexdoc', + 'v/latest/main/renders/minecraft/textures/gui/hexdoc/crafting_table.png', + 'v/latest/main/renders/minecraft/textures/item', + 'v/latest/main/renders/minecraft/textures/item/enchanted_book.png', + 'v/latest/main/renders/minecraft/textures/mob_effect', + 'v/latest/main/renders/minecraft/textures/mob_effect/blindness.png', + 'v/latest/main/renders/minecraft/textures/mob_effect/conduit_power.png', + 'v/latest/main/renders/minecraft/textures/mob_effect/levitation.png', + 'v/latest/main/renders/minecraft/textures/mob_effect/nausea.png', + 'v/latest/main/renders/minecraft/textures/mob_effect/poison.png', ]) # --- diff --git a/test/integration/__snapshots__/test_copier/test_index[vlatestmainen_usindex.html].raw b/test/integration/__snapshots__/test_copier/test_index[vlatestmainen_usindex.html].raw index d98213c0..e5b34e50 100644 --- a/test/integration/__snapshots__/test_copier/test_index[vlatestmainen_usindex.html].raw +++ b/test/integration/__snapshots__/test_copier/test_index[vlatestmainen_usindex.html].raw @@ -131,38 +131,38 @@
Amethyst Shard Getting Started + title="Amethyst Shard" + alt="Amethyst Shard" + src="../../../../v/latest/main/renders/minecraft/item/amethyst_shard.png" + loading="lazy" + class="item-texture texture pixelated " +> Getting Started
  • Nausea This is the online version of the {} documentation.
  • + title="Nausea" + alt="Nausea" + src="../../../../v/latest/main/renders/minecraft/textures/mob_effect/nausea.png" + loading="lazy" + class="item-texture texture pixelated " +> This is the online version of the {} documentation.
Amethyst Shard Mod Book + title="Amethyst Shard" + alt="Amethyst Shard" + src="../../../../v/latest/main/renders/minecraft/item/amethyst_shard.png" + loading="lazy" + class="item-texture texture pixelated " +> Mod Book
  • Nausea This is the online version of the {} documentation.
  • + title="Nausea" + alt="Nausea" + src="../../../../v/latest/main/renders/minecraft/textures/mob_effect/nausea.png" + loading="lazy" + class="item-texture texture pixelated " +> This is the online version of the {} documentation.
@@ -170,12 +170,12 @@

Amethyst Dust.

@@ -1268,16 +1270,16 @@
Spotlight inventory slot + alt="Spotlight inventory slot" + src="GITHUB_PAGES_URL/v/latest/main/renders/hexdoc/textures/gui/spotlight.png" + > Charged Amethyst + title="Charged Amethyst" + alt="Charged Amethyst" + src="../../../../v/latest/main/renders/hexcasting/item/charged_amethyst.png" + loading="lazy" + class="item-texture texture pixelated " +>

Finally, I'll rarely find a large crystal crackling with energy. This has about as much media inside as ten units of Amethyst Dust (or two Amethyst Shards).

@@ -1288,12 +1290,12 @@

Oak StaffStaffStaff

Scrying Lens

Focus

Abacus

Spellbook

Scrolls

Slates

Casting Items

Phials of Media

Pigments

Edified Trees

Jeweler's Hammer

Decorative Blocks

Impetuses

Directrices

@@ -1314,16 +1291,16 @@
Spotlight inventory slot + alt="Spotlight inventory slot" + src="GITHUB_PAGES_URL/v/latest/main/renders/hexdoc/textures/gui/spotlight.png" + > Charged Amethyst + title="Charged Amethyst" + alt="Charged Amethyst" + src="../../../../v/latest/main/renders/hexcasting/item/charged_amethyst.png" + loading="lazy" + class="item-texture texture pixelated " +>

Finally, I'll rarely find a large crystal crackling with energy. This has about as much media inside as ten units of Amethyst Dust (or two Amethyst Shards).

@@ -1334,12 +1311,12 @@

Oak StaffStavesStaves

Scrying Lens

Thought-Knot

Focus

Abacus

Spellbook

Scrolls

Slates

Casting Items

Phials of Media

Pigments

Edified Trees

Jeweler's Hammer

Decorative Blocks

Impeti

Directrices

Charged Amethyst Crystal apiece. The block itself is worth four of the shards.


@@ -9790,64 +9726,39 @@
Amethyst Dust
Crafting Table + title="Crafting Table" + alt="Crafting Table" + src="../../../../v/latest/main/renders/minecraft/textures/gui/hexdoc/crafting_table.png" + class="texture pixelated " +>
-
- Shard of Quenched Allay - Shard of Quenched Allay - Shard of Quenched Allay - Shard of Quenched Allay -
+ Shard of Quenched Allay
Amethyst Dust + title="Amethyst Dust" + alt="Amethyst Dust" + src="../../../../v/latest/main/renders/hexcasting/item/amethyst_dust.png" + loading="lazy" + class="item-texture texture pixelated multi-texture-active" +>
Amethyst Dust
31
+ title="Amethyst Dust" + alt="Amethyst Dust" + src="../../../../v/latest/main/renders/hexcasting/item/amethyst_dust.png" + loading="lazy" + class="item-texture texture pixelated " +>
31
@@ -9864,128 +9775,78 @@
Amethyst Shard
Crafting Table + title="Crafting Table" + alt="Crafting Table" + src="../../../../v/latest/main/renders/minecraft/textures/gui/hexdoc/crafting_table.png" + class="texture pixelated " +>
-
- Shard of Quenched Allay - Shard of Quenched Allay - Shard of Quenched Allay - Shard of Quenched Allay -
+ Shard of Quenched Allay
Amethyst Shard + title="Amethyst Shard" + alt="Amethyst Shard" + src="../../../../v/latest/main/renders/minecraft/item/amethyst_shard.png" + loading="lazy" + class="item-texture texture pixelated multi-texture-active" +>
Amethyst Shard
7
+ title="Amethyst Shard" + alt="Amethyst Shard" + src="../../../../v/latest/main/renders/minecraft/item/amethyst_shard.png" + loading="lazy" + class="item-texture texture pixelated " +>
7
Charged Amethyst
Crafting Table + title="Crafting Table" + alt="Crafting Table" + src="../../../../v/latest/main/renders/minecraft/textures/gui/hexdoc/crafting_table.png" + class="texture pixelated " +>
-
- Shard of Quenched Allay - Shard of Quenched Allay - Shard of Quenched Allay - Shard of Quenched Allay -
+ Shard of Quenched Allay
Charged Amethyst + title="Charged Amethyst" + alt="Charged Amethyst" + src="../../../../v/latest/main/renders/hexcasting/item/charged_amethyst.png" + loading="lazy" + class="item-texture texture pixelated multi-texture-active" +>
Charged Amethyst
4
+ title="Charged Amethyst" + alt="Charged Amethyst" + src="../../../../v/latest/main/renders/hexcasting/item/charged_amethyst.png" + loading="lazy" + class="item-texture texture pixelated " +>
4
@@ -9997,12 +9858,12 @@