diff --git a/client/admin/admin.jsx b/client/admin/admin.jsx index cc6eb72ca..a8ee10562 100644 --- a/client/admin/admin.jsx +++ b/client/admin/admin.jsx @@ -49,4 +49,4 @@ const Admin = ()=>{ ); }; -module.exports = Admin; +export default Admin; diff --git a/client/admin/admin.less b/client/admin/admin.less index 0fc353194..432f92e8b 100644 --- a/client/admin/admin.less +++ b/client/admin/admin.less @@ -1,11 +1,9 @@ -@import 'naturalcrit/styles/reset.less'; -@import 'naturalcrit/styles/elements.less'; -@import 'naturalcrit/styles/animations.less'; -@import 'naturalcrit/styles/colors.less'; -@import 'naturalcrit/styles/tooltip.less'; -@import './themes/fonts/iconFonts/fontAwesome.less'; - -@import 'font-awesome/css/font-awesome.css'; +@import '@sharedStyles/reset.less'; +@import '@sharedStyles/elements.less'; +@import '@sharedStyles/animations.less'; +@import '@sharedStyles/colors.less'; +@import '@sharedStyles/tooltip.less'; +@import '@themes/fonts/iconFonts/fontAwesome.less'; html,body, #reactContainer, .naturalCrit { min-height : 100%; } diff --git a/client/admin/brewUtils/brewUtils.less b/client/admin/brewUtils/brewUtils.less index 5bbbc3f69..cfa7dbbdf 100644 --- a/client/admin/brewUtils/brewUtils.less +++ b/client/admin/brewUtils/brewUtils.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/colors.less'; + .brewUtil { .result { margin-top : 20px; diff --git a/client/admin/main.jsx b/client/admin/main.jsx new file mode 100644 index 000000000..a5b7c84ad --- /dev/null +++ b/client/admin/main.jsx @@ -0,0 +1,6 @@ +import { createRoot } from 'react-dom/client'; +import Admin from './admin.jsx'; + +const props = window.__INITIAL_PROPS__ || {}; + +createRoot(document.getElementById('reactRoot')).render(); diff --git a/client/components/codeEditor/autocompleteEmoji.js b/client/components/codeEditor/autocompleteEmoji.js index d5a3a71aa..fc64e7bbd 100644 --- a/client/components/codeEditor/autocompleteEmoji.js +++ b/client/components/codeEditor/autocompleteEmoji.js @@ -1,7 +1,7 @@ -import diceFont from 'themes/fonts/iconFonts/diceFont.js'; -import elderberryInn from 'themes/fonts/iconFonts/elderberryInn.js'; -import fontAwesome from 'themes/fonts/iconFonts/fontAwesome.js'; -import gameIcons from 'themes/fonts/iconFonts/gameIcons.js'; +import diceFont from '@themes/fonts/iconFonts/diceFont.js'; +import elderberryInn from '@themes/fonts/iconFonts/elderberryInn.js'; +import fontAwesome from '@themes/fonts/iconFonts/fontAwesome.js'; +import gameIcons from '@themes/fonts/iconFonts/gameIcons.js'; const emojis = { ...diceFont, diff --git a/client/components/codeEditor/codeEditor.less b/client/components/codeEditor/codeEditor.less index c8e60974b..89d0c9497 100644 --- a/client/components/codeEditor/codeEditor.less +++ b/client/components/codeEditor/codeEditor.less @@ -5,10 +5,10 @@ @import (less) 'codemirror/addon/hint/show-hint.css'; //Icon fonts included so they can appear in emoji autosuggest dropdown -@import (less) './themes/fonts/iconFonts/diceFont.less'; -@import (less) './themes/fonts/iconFonts/elderberryInn.less'; -@import (less) './themes/fonts/iconFonts/gameIcons.less'; -@import (less) './themes/fonts/iconFonts/fontAwesome.less'; +@import (less) '@themes/fonts/iconFonts/diceFont.less'; +@import (less) '@themes/fonts/iconFonts/elderberryInn.less'; +@import (less) '@themes/fonts/iconFonts/gameIcons.less'; +@import (less) '@themes/fonts/iconFonts/fontAwesome.less'; @keyframes sourceMoveAnimation { 50% { color : white;background-color : red;} diff --git a/client/components/combobox.jsx b/client/components/combobox.jsx index 5060b8ecf..7c015d3d6 100644 --- a/client/components/combobox.jsx +++ b/client/components/combobox.jsx @@ -11,16 +11,17 @@ const Combobox = createReactClass({ trigger : 'hover', default : '', placeholder : '', - tooltip: '', + tooltip : '', autoSuggest : { clearAutoSuggestOnClick : true, suggestMethod : 'includes', filterOn : [] // should allow as array to filter on multiple attributes, or even custom filter }, - valuePatterns: /.+/ + valuePatterns : /.+/ }; }, getInitialState : function() { + this.dropdownRef = React.createRef(); return { showDropdown : false, value : '', @@ -41,7 +42,7 @@ const Combobox = createReactClass({ }, handleClickOutside : function(e){ // Close dropdown when clicked outside - if(this.refs.dropdown && !this.refs.dropdown.contains(e.target)) { + if(this.dropdownRef.current && !this.dropdownRef.current.contains(e.target)) { this.handleDropdown(false); } }, @@ -88,7 +89,7 @@ const Combobox = createReactClass({ } }} onKeyDown={(e)=>{ - if (e.key === "Enter") { + if(e.key === 'Enter') { e.preventDefault(); this.props.onEntry(e); } @@ -128,7 +129,7 @@ const Combobox = createReactClass({ }); return (
{this.handleDropdown(false);} : undefined}> {this.renderTextInput()} {this.renderDropdown(dropdownChildren)} diff --git a/client/components/renderWarnings/renderWarnings.less b/client/components/renderWarnings/renderWarnings.less index 70799092a..a1413709b 100644 --- a/client/components/renderWarnings/renderWarnings.less +++ b/client/components/renderWarnings/renderWarnings.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/colors.less'; + .renderWarnings { position : relative; float : right; diff --git a/client/components/splitPane/splitPane.less b/client/components/splitPane/splitPane.less index 80a8695af..779d0c222 100644 --- a/client/components/splitPane/splitPane.less +++ b/client/components/splitPane/splitPane.less @@ -1,3 +1,4 @@ +@import '@sharedStyles/core.less'; .splitPane { position : relative; diff --git a/client/homebrew/brewRenderer/brewRenderer.jsx b/client/homebrew/brewRenderer/brewRenderer.jsx index 22bb734fb..b7c23d981 100644 --- a/client/homebrew/brewRenderer/brewRenderer.jsx +++ b/client/homebrew/brewRenderer/brewRenderer.jsx @@ -1,10 +1,12 @@ /*eslint max-lines: ["warn", {"max": 300, "skipBlankLines": true, "skipComments": true}]*/ +import brewRendererStylesUrl from './brewRenderer.less?url'; +import headerNavStylesUrl from './headerNav/headerNav.less?url'; import './brewRenderer.less'; import React, { useState, useRef, useMemo, useEffect } from 'react'; import _ from 'lodash'; -import MarkdownLegacy from '../../../shared/markdownLegacy.js'; -import Markdown from '../../../shared/markdown.js'; +import MarkdownLegacy from '@shared/markdownLegacy.js'; +import Markdown from '@shared/markdown.js'; import ErrorBar from './errorBar/errorBar.jsx'; import ToolBar from './toolBar/toolBar.jsx'; @@ -13,10 +15,10 @@ import RenderWarnings from '../../components/renderWarnings/renderWarnings.jsx'; import NotificationPopup from './notificationPopup/notificationPopup.jsx'; import Frame from 'react-frame-component'; import dedent from 'dedent'; -import { printCurrentBrew } from '../../../shared/helpers.js'; +import { printCurrentBrew } from '@shared/helpers.js'; import HeaderNav from './headerNav/headerNav.jsx'; -import { safeHTML } from './safeHTML.js'; +import safeHTML from './safeHTML.js'; const PAGEBREAK_REGEX_V3 = /^(?=\\page(?:break)?(?: *{[^\n{}]*})?$)/m; const PAGEBREAK_REGEX_LEGACY = /\\page(?:break)?/m; @@ -29,6 +31,8 @@ const INITIAL_CONTENT = dedent` + +
`; @@ -343,6 +347,9 @@ const BrewRenderer = (props)=>{
{headerState ? : <>} + {state.isMounted && +
+ } ); }; diff --git a/client/homebrew/brewRenderer/brewRenderer.less b/client/homebrew/brewRenderer/brewRenderer.less index 5769a13df..ea9b43d75 100644 --- a/client/homebrew/brewRenderer/brewRenderer.less +++ b/client/homebrew/brewRenderer/brewRenderer.less @@ -1,4 +1,4 @@ -@import (multiple, less) 'shared/naturalcrit/styles/reset.less'; +@import '@sharedStyles/core.less'; .brewRenderer { height : 100vh; diff --git a/client/homebrew/brewRenderer/errorBar/errorBar.less b/client/homebrew/brewRenderer/errorBar/errorBar.less index 163648533..528521a07 100644 --- a/client/homebrew/brewRenderer/errorBar/errorBar.less +++ b/client/homebrew/brewRenderer/errorBar/errorBar.less @@ -1,3 +1,4 @@ +@import '@sharedStyles/colors.less'; .errorBar { position : absolute; diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx index dd05391f0..5f4fc5608 100644 --- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx +++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.jsx @@ -1,7 +1,7 @@ import './notificationPopup.less'; import React, { useEffect, useState } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from 'markdown.js'; +import Markdown from '@shared/markdown.js'; import Dialog from '../../../components/dialog.jsx'; diff --git a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less index 85d4c8365..4f34bad8d 100644 --- a/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less +++ b/client/homebrew/brewRenderer/notificationPopup/notificationPopup.less @@ -1,3 +1,5 @@ +@import './client/homebrew/navbar/navbar.less'; + .popups { position : fixed; top : calc(@navbarHeight + @viewerToolsHeight); diff --git a/client/homebrew/brewRenderer/safeHTML.js b/client/homebrew/brewRenderer/safeHTML.js index 2574f4cfe..d9438b663 100644 --- a/client/homebrew/brewRenderer/safeHTML.js +++ b/client/homebrew/brewRenderer/safeHTML.js @@ -43,4 +43,4 @@ function safeHTML(htmlString) { return div.innerHTML; }; -module.exports.safeHTML = safeHTML; \ No newline at end of file +export default safeHTML; \ No newline at end of file diff --git a/client/homebrew/editor/editor.jsx b/client/homebrew/editor/editor.jsx index 9707fe84f..06fd469a0 100644 --- a/client/homebrew/editor/editor.jsx +++ b/client/homebrew/editor/editor.jsx @@ -4,7 +4,7 @@ import React from 'react'; import createReactClass from 'create-react-class'; import _ from 'lodash'; import dedent from 'dedent'; -import Markdown from '../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import CodeEditor from '../../components/codeEditor/codeEditor.jsx'; import SnippetBar from './snippetbar/snippetbar.jsx'; @@ -88,7 +88,7 @@ const Editor = createReactClass({ const snippetBar = document.querySelector('.editor > .snippetBar'); if(!snippetBar) return; - this.resizeObserver = new ResizeObserver(entries=>{ + this.resizeObserver = new ResizeObserver((entries)=>{ const height = document.querySelector('.editor > .snippetBar').offsetHeight; this.setState({ snippetBarHeight: height }); }); diff --git a/client/homebrew/editor/editor.less b/client/homebrew/editor/editor.less index d7b51a428..3851b50c5 100644 --- a/client/homebrew/editor/editor.less +++ b/client/homebrew/editor/editor.less @@ -1,4 +1,6 @@ -@import 'themes/codeMirror/customEditorStyles.less'; +@import '@sharedStyles/core.less'; +@import '@themes/codeMirror/customEditorStyles.less'; + .editor { position : relative; width : 100%; diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.jsx b/client/homebrew/editor/metadataEditor/metadataEditor.jsx index 281d62c93..8d6ccb890 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.jsx +++ b/client/homebrew/editor/metadataEditor/metadataEditor.jsx @@ -7,7 +7,8 @@ import request from '../../utils/request-middleware.js'; import Combobox from '../../../components/combobox.jsx'; import TagInput from '../tagInput/tagInput.jsx'; -import Themes from 'themes/themes.json'; + +import Themes from '@themes/themes.json'; import validations from './validations.js'; import homebreweryThumbnail from '../../thumbnail.png'; @@ -337,9 +338,9 @@ const MetadataEditor = createReactClass({ {this.renderThumbnail()} -
+
-
+
- + {this.renderLanguageDropdown()} @@ -362,9 +363,9 @@ const MetadataEditor = createReactClass({ {this.renderAuthors()} -
+
-
+
- +

Privacy

diff --git a/client/homebrew/editor/metadataEditor/metadataEditor.less b/client/homebrew/editor/metadataEditor/metadataEditor.less index e684037e2..6a4df1c46 100644 --- a/client/homebrew/editor/metadataEditor/metadataEditor.less +++ b/client/homebrew/editor/metadataEditor/metadataEditor.less @@ -1,4 +1,4 @@ -@import 'naturalcrit/styles/colors.less'; +@import '@sharedStyles/core.less'; .userThemeName { padding-right : 10px; diff --git a/client/homebrew/editor/snippetbar/snippetbar.jsx b/client/homebrew/editor/snippetbar/snippetbar.jsx index b6e977ea2..304664ff5 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.jsx +++ b/client/homebrew/editor/snippetbar/snippetbar.jsx @@ -7,13 +7,13 @@ import _ from 'lodash'; import cx from 'classnames'; import { loadHistory } from '../../utils/versionHistory.js'; -import { brewSnippetsToJSON } from '../../../../shared/helpers.js'; +import { brewSnippetsToJSON } from '@shared/helpers.js'; -import Legacy5ePHB from 'themes/Legacy/5ePHB/snippets.js'; -import V3_5ePHB from 'themes/V3/5ePHB/snippets.js'; -import V3_5eDMG from 'themes/V3/5eDMG/snippets.js'; -import V3_Journal from 'themes/V3/Journal/snippets.js'; -import V3_Blank from 'themes/V3/Blank/snippets.js'; +import Legacy5ePHB from '@themes/Legacy/5ePHB/snippets.js'; +import V3_5ePHB from '@themes/V3/5ePHB/snippets.js'; +import V3_5eDMG from '@themes/V3/5eDMG/snippets.js'; +import V3_Journal from '@themes/V3/Journal/snippets.js'; +import V3_Blank from '@themes/V3/Blank/snippets.js'; const ThemeSnippets = { Legacy_5ePHB : Legacy5ePHB, @@ -23,7 +23,7 @@ const ThemeSnippets = { V3_Blank : V3_Blank, }; -import EditorThemes from 'build/homebrew/codeMirror/editorThemes.json'; +import EditorThemes from '../../../../build/homebrew/codeMirror/editorThemes.json'; const execute = function(val, props){ if(_.isFunction(val)) return val(props); diff --git a/client/homebrew/editor/snippetbar/snippetbar.less b/client/homebrew/editor/snippetbar/snippetbar.less index 8e50aa764..37853ca75 100644 --- a/client/homebrew/editor/snippetbar/snippetbar.less +++ b/client/homebrew/editor/snippetbar/snippetbar.less @@ -1,5 +1,6 @@ +@import '@sharedStyles/core.less'; @import (less) './client/icons/customIcons.less'; -@import (less) '././././themes/fonts/5e/fonts.less'; +@import (less) '@themes/fonts/5e/fonts.less'; .snippetBar { @menuHeight : 25px; diff --git a/client/homebrew/editor/tagInput/curatedTagSuggestionList.js b/client/homebrew/editor/tagInput/curatedTagSuggestionList.js index d433175ef..7d692ecb0 100644 --- a/client/homebrew/editor/tagInput/curatedTagSuggestionList.js +++ b/client/homebrew/editor/tagInput/curatedTagSuggestionList.js @@ -1,210 +1,219 @@ -export default [ +export const tagSuggestionList = [ // ############################## Systems // D&D - "system:D&D Original", - "system:D&D Basic", - "system:AD&D 1e", - "system:AD&D 2e", - "system:D&D 3e", - "system:D&D 3.5e", - "system:D&D 4e", - "system:D&D 5e", - "system:D&D 5e 2024", - "system:BD&D (B/X)", - "system:D&D Essentials", + 'system:D&D Original', + 'system:D&D Basic', + 'system:AD&D 1e', + 'system:AD&D 2e', + 'system:D&D 3e', + 'system:D&D 3.5e', + 'system:D&D 4e', + 'system:D&D 5e', + 'system:D&D 5e 2024', + 'system:BD&D (B/X)', + 'system:D&D Essentials', // Other Famous RPGs - "system:Pathfinder 1e", - "system:Pathfinder 2e", - "system:Vampire: The Masquerade", - "system:Werewolf: The Apocalypse", - "system:Mage: The Ascension", - "system:Call of Cthulhu", - "system:Shadowrun", - "system:Star Wars RPG (D6/D20/Edge of the Empire)", - "system:Warhammer Fantasy Roleplay", - "system:Cyberpunk 2020", - "system:Blades in the Dark", - "system:Daggerheart", - "system:Draw Steel", - "system:Mutants and Masterminds", + 'system:Pathfinder 1e', + 'system:Pathfinder 2e', + 'system:Vampire: The Masquerade', + 'system:Werewolf: The Apocalypse', + 'system:Mage: The Ascension', + 'system:Call of Cthulhu', + 'system:Shadowrun', + 'system:Star Wars RPG (D6/D20/Edge of the Empire)', + 'system:Warhammer Fantasy Roleplay', + 'system:Cyberpunk 2020', + 'system:Blades in the Dark', + 'system:Daggerheart', + 'system:Draw Steel', + 'system:Mutants and Masterminds', // Meta - "meta:V3", - "meta:Legacy", - "meta:Template", - "meta:Theme", - "meta:free", - "meta:Character Sheet", - "meta:Documentation", - "meta:NPC", - "meta:Guide", - "meta:Resource", - "meta:Notes", - "meta:Example", + 'meta:V3', + 'meta:Legacy', + 'meta:Template', + 'meta:Theme', + 'meta:free', + 'meta:Character Sheet', + 'meta:Documentation', + 'meta:NPC', + 'meta:Guide', + 'meta:Resource', + 'meta:Notes', + 'meta:Example', // Book type - "type:Campaign", - "type:Campaign Setting", - "type:Adventure", - "type:One-Shot", - "type:Setting", - "type:World", - "type:Lore", - "type:History", - "type:Dungeon Master", - "type:Encounter Pack", - "type:Encounter", - "type:Session Notes", - "type:reference", - "type:Handbook", - "type:Manual", - "type:Manuals", - "type:Compendium", - "type:Bestiary", + 'type:Campaign', + 'type:Campaign Setting', + 'type:Adventure', + 'type:One-Shot', + 'type:Setting', + 'type:World', + 'type:Lore', + 'type:History', + 'type:Dungeon Master', + 'type:Encounter Pack', + 'type:Encounter', + 'type:Session Notes', + 'type:reference', + 'type:Handbook', + 'type:Manual', + 'type:Manuals', + 'type:Compendium', + 'type:Bestiary', // ###################################### RPG Keywords // Classes / Subclasses / Archetypes - "Class", - "Subclass", - "Archetype", - "Martial", - "Half-Caster", - "Full Caster", - "Artificer", - "Barbarian", - "Bard", - "Cleric", - "Druid", - "Fighter", - "Monk", - "Paladin", - "Rogue", - "Sorcerer", - "Warlock", - "Wizard", + 'Class', + 'Subclass', + 'Archetype', + 'Martial', + 'Half-Caster', + 'Full Caster', + 'Artificer', + 'Barbarian', + 'Bard', + 'Cleric', + 'Druid', + 'Fighter', + 'Monk', + 'Paladin', + 'Rogue', + 'Sorcerer', + 'Warlock', + 'Wizard', // Races / Species / Lineages - "Race", - "Ancestry", - "Lineage", - "Aasimar", - "Beastfolk", - "Dragonborn", - "Dwarf", - "Elf", - "Goblin", - "Half-Elf", - "Half-Orc", - "Human", - "Kobold", - "Lizardfolk", - "Lycan", - "Orc", - "Tiefling", - "Vampire", - "Yuan-Ti", + 'Race', + 'Ancestry', + 'Lineage', + 'Aasimar', + 'Beastfolk', + 'Dragonborn', + 'Dwarf', + 'Elf', + 'Goblin', + 'Half-Elf', + 'Half-Orc', + 'Human', + 'Kobold', + 'Lizardfolk', + 'Lycan', + 'Orc', + 'Tiefling', + 'Vampire', + 'Yuan-Ti', // Magic / Spells / Items - "Magic", - "Magic Item", - "Magic Items", - "Wondrous Item", - "Magic Weapon", - "Artifact", - "Spell", - "Spells", - "Cantrip", - "Cantrips", - "Eldritch", - "Eldritch Invocation", - "Invocation", - "Invocations", - "Pact boon", - "Pact Boon", - "Spellcaster", - "Spellblade", - "Magical Tattoos", - "Enchantment", - "Enchanted", - "Attunement", - "Requires Attunement", - "Rune", - "Runes", - "Wand", - "Rod", - "Scroll", - "Potion", - "Potions", - "Item", - "Items", - "Bag of Holding", + 'Magic', + 'Magic Item', + 'Magic Items', + 'Wondrous Item', + 'Magic Weapon', + 'Artifact', + 'Spell', + 'Spells', + 'Cantrip', + 'Cantrips', + 'Eldritch', + 'Eldritch Invocation', + 'Invocation', + 'Invocations', + 'Pact boon', + 'Pact Boon', + 'Spellcaster', + 'Spellblade', + 'Magical Tattoos', + 'Enchantment', + 'Enchanted', + 'Attunement', + 'Requires Attunement', + 'Rune', + 'Runes', + 'Wand', + 'Rod', + 'Scroll', + 'Potion', + 'Potions', + 'Item', + 'Items', + 'Bag of Holding', // Monsters / Creatures / Enemies - "Monster", - "Creatures", - "Creature", - "Beast", - "Beasts", - "Humanoid", - "Undead", - "Fiend", - "Aberration", - "Ooze", - "Giant", - "Dragon", - "Monstrosity", - "Demon", - "Devil", - "Elemental", - "Construct", - "Constructs", - "Boss", - "BBEG", + 'Monster', + 'Creatures', + 'Creature', + 'Beast', + 'Beasts', + 'Humanoid', + 'Undead', + 'Fiend', + 'Aberration', + 'Ooze', + 'Giant', + 'Dragon', + 'Monstrosity', + 'Demon', + 'Devil', + 'Elemental', + 'Construct', + 'Constructs', + 'Boss', + 'BBEG', // ############################# Media / Pop Culture - "One Piece", - "Dragon Ball", - "Dragon Ball Z", - "Naruto", - "Jujutsu Kaisen", - "Fairy Tail", - "Final Fantasy", - "Kingdom Hearts", - "Elder Scrolls", - "Skyrim", - "WoW", - "World of Warcraft", - "Marvel Comics", - "DC Comics", - "Pokemon", - "League of Legends", - "Runeterra", - "Arcane", - "Yu-Gi-Oh", - "Minecraft", - "Don't Starve", - "Witcher", - "Witcher 3", - "Cyberpunk", - "Cyberpunk 2077", - "Fallout", - "Divinity Original Sin 2", - "Fullmetal Alchemist", - "Fullmetal Alchemist Brotherhood", - "Lobotomy Corporation", - "Bloodborne", - "Dragonlance", - "Shackled City Adventure Path", - "Baldurs Gate 3", - "Library of Ruina", - "Radiant Citadel", - "Ravenloft", - "Forgotten Realms", - "Exandria", - "Critical Role", - "Star Wars", - "SW5e", - "Star Wars 5e", + 'One Piece', + 'Dragon Ball', + 'Dragon Ball Z', + 'Naruto', + 'Jujutsu Kaisen', + 'Fairy Tail', + 'Final Fantasy', + 'Kingdom Hearts', + 'Elder Scrolls', + 'Skyrim', + 'WoW', + 'World of Warcraft', + 'Marvel Comics', + 'DC Comics', + 'Pokemon', + 'League of Legends', + 'Runeterra', + 'Arcane', + 'Yu-Gi-Oh', + 'Minecraft', + 'Don\'t Starve', + 'Witcher', + 'Witcher 3', + 'Cyberpunk', + 'Cyberpunk 2077', + 'Fallout', + 'Divinity Original Sin 2', + 'Fullmetal Alchemist', + 'Fullmetal Alchemist Brotherhood', + 'Lobotomy Corporation', + 'Bloodborne', + 'Dragonlance', + 'Shackled City Adventure Path', + 'Baldurs Gate 3', + 'Library of Ruina', + 'Radiant Citadel', + 'Ravenloft', + 'Forgotten Realms', + 'Exandria', + 'Critical Role', + 'Star Wars', + 'SW5e', + 'Star Wars 5e', ]; + +// substrings to be normalized to the first value on the array +export const canonizationList = [ + ['5e 2024', '5.5e', '5e\'24', '5.24', '5e24', '5.5'], + ['5e', '5th Edition'], + ['Dungeons & Dragons', 'Dungeons and Dragons', 'Dungeons n dragons'], + ['D&D', 'DnD', 'dnd', 'Dnd', 'dnD', 'd&d', 'd&D', 'D&d'], + ['P2e', 'p2e', 'P2E', 'Pathfinder 2e'], +]; \ No newline at end of file diff --git a/client/homebrew/editor/tagInput/tagInput.jsx b/client/homebrew/editor/tagInput/tagInput.jsx index 7f4a3a77f..b43797424 100644 --- a/client/homebrew/editor/tagInput/tagInput.jsx +++ b/client/homebrew/editor/tagInput/tagInput.jsx @@ -1,71 +1,62 @@ -import "./tagInput.less"; -import React, { useState, useEffect } from "react"; -import Combobox from "../../../components/combobox.jsx"; +import './tagInput.less'; +import React, { useState, useEffect } from 'react'; +import Combobox from '../../../components/combobox.jsx'; -import tagSuggestionList from "./curatedTagSuggestionList.js"; +import { tagSuggestionList, canonizationList } from './curatedTagSuggestionList.js'; -const TagInput = ({tooltip, label, valuePatterns, values = [], unique = true, placeholder = "", smallText = "", onChange }) => { +const TagInput = ({ tooltip, label, valuePatterns, values = [], unique = true, placeholder = '', smallText = '', onChange })=>{ const [tagList, setTagList] = useState( - values.map((value) => ({ + values.map((value)=>({ value, - editing: false, - draft: "", + editing : false, + draft : '', })), ); - useEffect(() => { + useEffect(()=>{ const incoming = values || []; - const current = tagList.map((t) => t.value); + const current = tagList.map((t)=>t.value); - const changed = incoming.length !== current.length || incoming.some((v, i) => v !== current[i]); + const changed = incoming.length !== current.length || incoming.some((v, i)=>v !== current[i]); - if (changed) { + if(changed) { setTagList( - incoming.map((value) => ({ + incoming.map((value)=>({ value, - editing: false, + editing : false, })), ); } }, [values]); - useEffect(() => { + useEffect(()=>{ onChange?.({ - target: { value: tagList.map((t) => t.value) }, + target : { value: tagList.map((t)=>t.value) }, }); }, [tagList]); - // substrings to be normalized to the first value on the array - const duplicateGroups = [ - ["5e 2024", "5.5e", "5e'24", "5.24", "5e24", "5.5"], - ["5e", "5th Edition"], - ["Dungeons & Dragons", "Dungeons and Dragons", "Dungeons n dragons"], - ["D&D", "DnD", "dnd", "Dnd", "dnD", "d&d", "d&D", "D&d"], - ["P2e", "p2e", "P2E", "Pathfinder 2e"], - ]; - - const normalizeValue = (input) => { + const normalizeValue = (input)=>{ const lowerInput = input.toLowerCase(); let normalizedTag = input; - for (const group of duplicateGroups) { + for (const group of canonizationList) { for (const tag of group) { - if (!tag) continue; + if(!tag) continue; const index = lowerInput.indexOf(tag.toLowerCase()); - if (index !== -1) { + if(index !== -1) { normalizedTag = input.slice(0, index) + group[0] + input.slice(index + tag.length); break; } } } - if (normalizedTag.includes(":")) { - const [rawType, rawValue = ""] = normalizedTag.split(":"); + if(normalizedTag.includes(':')) { + const [rawType, rawValue = ''] = normalizedTag.split(':'); const tagType = rawType.trim().toLowerCase(); const tagValue = rawValue.trim(); - if (tagValue.length > 0) { + if(tagValue.length > 0) { normalizedTag = `${tagType}:${tagValue[0].toUpperCase()}${tagValue.slice(1)}`; } //trims spaces around colon and capitalizes the first word after the colon @@ -75,56 +66,56 @@ const TagInput = ({tooltip, label, valuePatterns, values = [], unique = true, pl return normalizedTag; }; - const submitTag = (newValue, index = null) => { + const submitTag = (newValue, index = null)=>{ const trimmed = newValue?.trim(); - if (!trimmed) return; - if (!valuePatterns.test(trimmed)) return; + if(!trimmed) return; + if(!valuePatterns.test(trimmed)) return; const normalizedTag = normalizeValue(trimmed); - setTagList((prev) => { - const existsIndex = prev.findIndex((t) => t.value.toLowerCase() === normalizedTag.toLowerCase()); - if (unique && existsIndex !== -1) return prev; - if (index !== null) { - return prev.map((t, i) => (i === index ? { ...t, value: normalizedTag, editing: false } : t)); + setTagList((prev)=>{ + const existsIndex = prev.findIndex((t)=>t.value.toLowerCase() === normalizedTag.toLowerCase()); + if(unique && existsIndex !== -1) return prev; + if(index !== null) { + return prev.map((t, i)=>(i === index ? { ...t, value: normalizedTag, editing: false } : t)); } return [...prev, { value: normalizedTag, editing: false }]; }); }; - const removeTag = (index) => { - setTagList((prev) => prev.filter((_, i) => i !== index)); + const removeTag = (index)=>{ + setTagList((prev)=>prev.filter((_, i)=>i !== index)); }; - const editTag = (index) => { - setTagList((prev) => prev.map((t, i) => (i === index ? { ...t, editing: true, draft: t.value } : t))); + const editTag = (index)=>{ + setTagList((prev)=>prev.map((t, i)=>(i === index ? { ...t, editing: true, draft: t.value } : t))); }; - const stopEditing = (index) => { - setTagList((prev) => prev.map((t, i) => (i === index ? { ...t, editing: false, draft: "" } : t))); + const stopEditing = (index)=>{ + setTagList((prev)=>prev.map((t, i)=>(i === index ? { ...t, editing: false, draft: '' } : t))); }; - const suggestionOptions = tagSuggestionList.map((tag) => { - const tagType = tag.split(":"); + const suggestionOptions = tagSuggestionList.map((tag)=>{ + const tagType = tag.split(':'); - let classes = "item"; + let classes = 'item'; switch (tagType[0]) { - case "type": - classes = "item type"; - break; - case "group": - classes = "item group"; - break; - case "meta": - classes = "item meta"; - break; - case "system": - classes = "item system"; - break; - default: - classes = "item"; - break; + case 'type': + classes = 'item type'; + break; + case 'group': + classes = 'item group'; + break; + case 'meta': + classes = 'item meta'; + break; + case 'system': + classes = 'item system'; + break; + default: + classes = 'item'; + break; } return ( @@ -135,73 +126,69 @@ const TagInput = ({tooltip, label, valuePatterns, values = [], unique = true, pl }); return ( -
+
submitTag(value)} - onEntry={(e) => { - if (e.key === "Enter") { + onSelect={(value)=>submitTag(value)} + onEntry={(e)=>{ + if(e.key === 'Enter') { e.preventDefault(); submitTag(e.target.value); } }} /> -
    - {tagList.map((t, i) => - t.editing ? ( - - setTagList((prev) => - prev.map((tag, idx) => (idx === i ? { ...tag, draft: e.target.value } : tag)), - ) +
      + {tagList.map((t, i)=>t.editing ? ( + setTagList((prev)=>prev.map((tag, idx)=>(idx === i ? { ...tag, draft: e.target.value } : tag)), + ) + } + onKeyDown={(e)=>{ + if(e.key === 'Enter') { + e.preventDefault(); + submitTag(t.draft, i); // submit draft + setTagList((prev)=>prev.map((tag, idx)=>(idx === i ? { ...tag, draft: '' } : tag)), + ); } - onKeyDown={(e) => { - if (e.key === "Enter") { - e.preventDefault(); - submitTag(t.draft, i); // submit draft - setTagList((prev) => - prev.map((tag, idx) => (idx === i ? { ...tag, draft: "" } : tag)), - ); - } - if (e.key === "Escape") { - stopEditing(i); - e.target.blur(); - } - }} - autoFocus - /> - ) : ( -
    • editTag(i)}> - {t.value} - -
    • - ), + if(e.key === 'Escape') { + stopEditing(i); + e.target.blur(); + } + }} + autoFocus + /> + ) : ( +
    • editTag(i)}> + {t.value} + +
    • + ), )}
diff --git a/client/homebrew/editor/tagInput/tagSuggestionList.js b/client/homebrew/editor/tagInput/tagSuggestionList.js index 6b8e4060e..eb4891616 100644 --- a/client/homebrew/editor/tagInput/tagSuggestionList.js +++ b/client/homebrew/editor/tagInput/tagSuggestionList.js @@ -1,1980 +1,1980 @@ export default [ - "meta:Theme", - "5e", - "Subclass", - "meta:theme", - "subclass", - "Class", - "Homebrew", - "Race", - "Dungeons and Dragons", - "theme", - "Daggerheart", - "2024", - "One Piece", - "One Piece DND", - "Luffy", - "Dungeons and Devil Fruits", - "Strawhats", - "Template", - "Campaign Frame", - "class", - "Players Handbook", - "dnd", - "osr", - "Dungeon Masters Guide", - "shadowdark", - "dragonbane", - "PHB", - "example", - "Devil Fruits", - "system:pf2e", - "DnD", - "DMG", - "system:dnd5.5", - "Monster", - "homebrew", - "race", - "template", - "Warlock", - "monster", - "Fighter", - "warlock", - "druid", - "sorcerer", - "D&D", - "Magic Item", - "Barbarian", - "Artificer", - "2014", - "system:descent into avernus", - "Sorcerer", - "Adventure", - "Paladin", - "Ranger", - "user help", - "fighter", - "5th Edition", - "Spells", - "Monk", - "Spell", - "NPC", - "Cleric", - "spell", - "Rogue", - "css", - "Item", - "artificer", - "magic item", - "Rules", - "barbarian", - "wizard", - "russian", - "DnD5e", - "Wizard", - "paladin", - "bastionland", - "spells", - "Devil Fruit", - "Bard", - "5.5e", - "rogue", - "Tabletop System", - "Haki", - "Druid", - "mystic bastionland", - "item", - "Lore", - "bard", - "monk", - "system:dnd5e", - "world", - "ranger", - "WIP", - "cleric", - "Dragon", - "Naruto", - "Creature", - "snippet", - "npc", - "DeS", - "Magic", - "guide", - "v3", - "Beast", - "Classe", - "onering", - "Monsters", - "Races", - "Weapon", - "adventure", - "Subclasses", - "stat block", - "weapon", - "Species", - "DONE", - "archetype", - "RPG", - "Hollow Knight", - "5e'24", - "Martial", - "DND", - "Classe Nova", - "Curse of Strahd", - "Boss", - "Hollowed Kingdoms", - "baldurs mouth", - "5.24", - "Homewbrew", - "Encyclopedia", - "Revised", - "OneWorldHD", - "knight", - "DPS", - "srd", - "Undead", - "items", - "DnD 5e", - "Guide", - "Compendium", - "Feat", - "newspaper", - "magic", - "TTRPG", - "descent into avernus", - "reference", - "system:D&D 5e24", - "feat", - "Magic Items", - "Campaign", - "resource", - "Feats", - "Anime", - "dd5", - "races", - "Monstrosity", - "DM Screen", - "2024 Rules", - "Rework", - "Character Build", - "Done", - "5e 2024", - "Construct", - "myth", - "magic items", - "creature", - "Legendary", - "Strahd", - "background", - "Player", - "style", - "Legacy", - "Player Handbook", - "martial", - "Character", - "Dungeons & Dragons", - "Table", - "reddit", - "monsters", - "OneDND", - "dragon", - "Suporte", - "Soulbound", - "Expanded Handbook", - "bestiary", - "Humanoid", - "system:dnd", - "Oredell", - "system:class", - "V3", - "system:5e", - "5e'14", - "Age of Sigmar", - "Items", - "Eberron", - "horror", - "dnd5e", - "star wars", - "Background", - "compendium", - "revision", - "Elemental", - "character", - "Marcial", - "SW5e", - "notes", - "DM", - "Fey", - "one-shot", - "resources", - "NEW", - "campaign", - "wondrous item", - "Setting", - "Archive", - "NIMRE", - "Tanque", - "Jogavel", - "Dnd 5e", - "LotM", - "setting", - "revised", - "Warhammer", - "rework", - "Conjurador", - "GMBinder", - "ItemSet", - "NPCs", - "classes", - "CR 2", - "AetherSail", - "undead", - "Artifact", - "cards", - "Example", - "Guides", - "Theme", - "Swamp", - "CR 1", - "patron", - "Extra", - "concept", - "final fantasy", - "Aberration", - "Elder Scrolls", - "rules", - "meta:gratis", - "Dice Pool", - "Cue", - "dark", - "type:Style", - "rpg", - "meta:free", - "summoner", - "OC", - "rare", - "Fleshing Out", - "francais", - "Dnd", - "Creatures", - "Sims 4", - "sous-classe", - "ffxiv", - "Underdark", - "add-on", - "weapons", - "Subrace", - "dungeons and dragons", - "Naruto 5e", - "Lafari", - "Very Rare", - "d6", - "red", - "Equipment", - "CR 3", - "Patron", - "5E", - "objet magique", - "spellcaster", - "feats", - "5.24e", - "system:d&d5e", - "Rare", - "Thudnfer", - "daggerheart", - "CR 1/2", - "Archetype", - "dnd 5e", - "Pathfinder", - "lineage", - "Celestial", - "Support", - "species", - "ARCHIVED", - "Horror", - "humanoid", - "Subclase", - "book:PHB E&E", - "final fantasy xiv", - "Jungle", - "Feywild", - "Fiend", - "subclasses", - "HB", - "Legacy Challenge", - "Project Horizon", - "vampire", - "WoW", - "DND 5e", - "Weapons", - "system:book clone", - "CoS", - "N5e", - "Summon", - "Spellcaster", - "Koretra", - "Voidborn", - "one shot", - "Templates", - "tables", - "Iphexar", - "Shattered Obelisk", - "Sword Coast", - "elemental", - "lore", - "character sheet", - "discord", - "BetterMonsters", - "players", - "group:simple skans", - "Coastal", - "Forest", - "Unearthed Arcana", - "Old", - "Collection", - "Ancestry", - "Caevash", - "Strixhaven", - "Limbus Company", - "Daydreams & Deviants", - "Statblocks", - "Urban", - "Classes", - "familiar", - "Blood", - "oneshot", - "n5e", - "wip", - "masks", - "Planeshifted", - "Carrioss", - "avernus", - "object", - "1", - "Ruins", - "Anime Character", - "wild shape", - "mask", - "dj9 game", - "Handbook", - "Curse", - "oath", - "Midralis", - "Appendix", - "5.5", - "tales of the valiant", - "player classes", - "Caster", - "Large", - "Fateforge", - "Cursed", - "beast", - "Pathfinder 2e", - "Design", - "Uncommon", - "Endeur", - "Elemental Water", - "SCC", - "sci-fi", - "Dragons", - "human", - "Gods", - "Medium", - "System", - "Help", - "Handout", - "Skyrim", - "BnB", - "draft", - "PC", - "Variant", - "syntax", - "OneShot", - "Clase", - "UESTRPG", - "Savannah", - "Reef", - "CR 5", - "Forgotten Realms", - "collection", - "Combat", - "Historia", - "artifact", - "Expansion", - "Attunement", - "Variant Rules", - "d&d", - "Party Build", - "Evocation", - "homerule", - "Forbidden West", - "how-to", - "tov", - "Mystical Item", - "CR 4", - "Necromancer", - "General Rules", - "Needs Update", - "stat blocks", - "DC Comics", - "Sword", - "Armor", - "blood hunter", - "Blood Hunter", - "Meio Conjurador", - "Mydia", - "3rd Party", - "N5E", - "Delvebound", - "Ocean", - "Subterranean", - "half-caster", - "Demon", - "Fire", - "meta:Template", - "Character Sheet", - "PF2e", - "png", - "fantasy", - "Setting Guide", - "Style", - "Cor", - "legacy", - "Minion", - "meta:khaoz age", - "Book", - "magical item", - "immersion", - "reminder cards", - "Regras", - "Durnovar", - "2025", - "Camp1", - "Abyss", - "armor", - "construct", - "firearms", - "Backgrounds", - "Companion", - "Melee", - "fey", - "Incomplete", - "Vampire", - "Bestiary", - "Worldbuilding", - "History", - "Conjuration", - "necromancy", - "dragons", - "ancestry", - "Mech", - "PbtA", - "COS", - "One Shot", - "Factions", - "Transmutation", - "Spellcasting", - "card", - "Ardh", - "redveil", - "conditions", - "elturel", - "rhye", - "group:James Haeck", - "CaelYuu", - "system:5.24e", - "system:GM Binder", - "Grassland", - "melee", - "Potions", - "anime", - "D&D 5e", - "Healer", - "Gambling", - "Lightning", - "fighting style", - "support", - "Style Template", - "mtg", - "NSFW", - "aventura", - "Manuals", - "plant", - "Incarnate", - "Crafting", - "DnDBeyond", - "Monster Girl", - "Monster Girl Encyclopedia", - "pet", - "npcs", - "Stat Block", - "Styleguide", - "mitologia", - "Objeto maravilloso", - "vaesen rpg", - "dnd-2024", - "Class Handbook", - "Space", - "Taiga", - "CR 6", - "Pact Boon", - "race/ancestry", - "Necromancy", - "cantrip", - "LoL", - "Raza", - "handout", - "Mechanic", - "Conversion", - "Wondrous Item", - "Familiar", - "necromancer", - "uncommon", - "curse", - "Campaign Setting", - "Tetra", - "1e", - "module", - "Evolving", - "boiling sea", - "deck", - "OSR", - "RU", - "VL", - "Underdeep", - "Deep Ocean", - "Giant", - "statblock", - "combat", - "Time", - "5E24", - "session zero", - "elf", - "tank", - "sorcerous origin", - "Drakkenheim", - "Tavern", - "Domain", - "healer", - "Valenor", - "blood", - "Oath", - "spooky", - "fire", - "meta:5e24 Style", - "Notes", - "City", - "Conjurador Completo", - "prop", - "Dotherys", - "Rietuma 3.0", - "5e24", - "Library of Ruina", - "español", - "Project Echo", - "battle of Japan", - "Plant", - "Badlands", - "Neverwinter", - "Fantasy", - "Beastfolk", - "Unarmed", - "Cold", - "Damage", - "attunement", - "Hurthud", - "3rd Level", - "spelljammer", - "mostro", - "Custom", - "PT-BR", - "Alternative Realms", - "The Foot", - "boss", - "demo", - "Supplement", - "FitD", - "classe", - "5.14", - "Copy", - "DnD5e24", - "X-Men", - "TNA", - "CR 8", - "Desert", - "CR 7", - "arme", - "random", - "spellcasting", - "Deprecated", - "Cards", - "finished", - "Ben 10", - "equipment", - "Geography", - "Games", - "For Players", - "Faerun", - "scroll", - "Faction", - "Alchemist", - "drow", - "Lineage", - "mix-blend-mode", - "columns", - "User Help", - "Reami Dimenticati", - "Класс", - "D100", - "nsfw", - "hucaen", - "v1.0", - "Cortex", - "Fallout", - "ww5e", - "MAGIC", - "DnD2024", - "ToV", - "D&D2024", - "The Backrooms", - "Freshwater", - "D20", - "Dragonborn", - "custom", - "sword", - "Dungeons and Dragons 5e", - "Water", - "legendary", - "Dungeon", - "Ravenloft", - "aberration", - "Longsword", - "transmutation", - "Fairy Tail", - "Character background", - "Exandria", - "Updated", - "pitch", - "Half-Caster", - "Complete", - "Money", - "player", - "forgotten-realms", - "Festival", - "Casino", - "SCAG", - "Currency", - "North", - "Toril", - "Scourged Land of Valenor", - "Oota", - "parchment", - "Literature", - "Serrith", - "PNJ", - "Divinity Original Sin 2", - "Wild", - "videogame", - "magic the gathering", - "sweetblossom", - "GMscreen", - "MandM", - "D&D 5.24", - "Camp2", - "Remaster", - "riassunti", - "type:Resource", - "system:D&D", - "tag:Class", - "Excelsior", - "Stat Blocks", - "Sci-Fi", - "Ooze", - "CR 1/8", - "sublclass", - "chart", - "Mountains", - "guns", - "Nature", - "Orc", - "Poison", - "Devil", - "fiend", - "DC", - "pt-br", - "ABnB", - "One-Shot", - "strahd", - "Ring", - "Theme song", - "orc", - "summon", - "Psion", - "Psionics", - "Dungeon Master", - "vehicle", - "DM only", - "Demigod", - "Antica Energia", - "Pirates", - "Sourcebook", - "devil", - "Cantrip", - "mystery", - "MtG", - "conversion", - "Festivals", - "Casinos", - "Taverns", - "Betting", - "Drinking", - "phandelver", - "Warhammer 40k", - "mutant", - "styling", - "FATE", - "Lone Wolf", - "icon", - "New Dawn", - "Magic Set", - "Paladin Subclass", - "Alter Class", - "difficulty classses", - "combat tables", - "phb", - "Project Moon", - "Undertomes", - "EGO", - "Campagne 1", - "Constelação", - "Arvore I", - "Fim da Jornada", - "greek god", - "dwarf", - "Firearms", - "3.5e", - "generator", - "Elf", - "meta: Scenario", - "enchantment", - "buff", - "ITW", - "Tank", - "Archived", - "Martial Archetype", - "caster", - "BR", - "Knight", - "Utility", - "SWADE", - "Star Wars", - "pc", - "Mystic", - "Useful", - "Netherdeep", - "crafting", - "Sapient Undead", - "Maverick", - "Revision", - "Resource", - "Humblewood", - "one piece", - "Bag of Holding", - "medium", - "lightning", - "backgrounds", - "4th Level", - "path", - "BREAK-RPG", - "dark fantasy", - "Players", - "poison", - "psionic", - "gazook89", - "homebrew subclass", - "wild-wasteland", - "CWD", - "Paid", - "Tales of the Valiant", - "Dreadhold", - "arma", - "system:Mutants and Masterminds", - "#Tiefschlaf", - "Brew", - "Myra", - "Swashbuckler", - "dead by daylight", - "Exceptional", - "COD Zombies", - "Hills", - "Tundra", - "type:Campaign", - "wild magic", - "Food", - "Death", - "homebrew rules", - "Remake", - "Witcher", - "water", - "Pet", - "book", - "AAH", - "pact", - "Ice", - "Character Creation", - "animal", - "Pokemon", - "clase", - "5e14", - "DBZ", - "CLONE", - "Evil", - "Tarsere", - "Mythology", - "pf2e", - "Magical", - "type:race", - "Sorcerous Origin", - "Information", - "styles", - "Module", - "gish", - "frames", - "DeltaGreen", - "Magic item", - "food", - "chef", - "basics", - "giant", - "Brew Creation", - "One-shot", - "ttrpg", - "Path", - "Don't Starve", - "MGE", - "firearm", - "DnDBehindTheScreen", - "store", - "The Artisan", - "timeline", - "college", - "dev", - "dungeon of the dead three", - "Cradle", - "Dnd5e", - "dungeon", - "Amaranthine", - "Regno di Oltremare", - "bestia", - "rewrite", - "WiP", - "Subclasse", - "mutants and masterminds", - "The Embrace", - "meta:documentation", - "Mutants And Masterminds", - "khedoria", - "Encounter Pack", - "giorni", - "Statblock", - "Enemies", - "Goblinoids", - "Heavens", - "system:2e", - "Vaalbara", - "Dwarf", - "airos", - "table", - "Artificer Specialization", - "Buff", - "Book 1", - "Ranged", - "cypher", - "utilities", - "40k", - "Psychic", - "Fear", - "steampunk", - "shadow", - "subclase", - "Barbarian Subclass", - "Elements", - "pact boon", - "Clan", - "Fly", - "solo", - "sourcebook", - "Marvel Comics", - "compilation", - "Firearm", - "sidekick", - "infusions", - "Mechanics", - "Summoner", - "Aasimar", - "Human", - "Vehicle", - "Shadow", - "Clone", - "custom css", - "ocean", - "sotdl", - "bandit", - "Wind", - "Printer Friendly", - "Obsolete", - "mechanics", - "illusion", - "5th edition", - "League of Legends", - "Vestige", - "dungeons", - "Dungeons", - "and", - "Elden Ring", - "L5R", - "d20", - "Poisons", - "d15", - "Dungeons And Dragons", - "MTG", - "divine", - "characters", - "witch", - "Anime Homebrew", - "Zombie", - "thunder", - "Jujutsu Kaisen", - "campagne", - "Deadlands", - "spell list", - "1 Person", - "Ritual", - "screen", - "nature", - "Divination", - "Compattare", - "dtrpg", - "quick ref", - "Mago", - "Illivia", - "Shonen", - "Core Deities", - "green ronin", - "Bless", - "D&D5e", - "version:0.1.0", - "curato", - "system:Ord", - "Images", - "Sealed Artifact", - "Giants", - "CR 9", - "CR 11", - "CR 0", - "CR 14", - "Shadowfell", - "Tier 1", - "d100", - "Elemental Air", - "artificiel", - "Cultist", - "Cyberpunk", - "Huge", - "Warrior", - "Gun", - "quest", - "LYRA", - "Music", - "Tiefling", - "Master", - "Witch", - "Linnorm", - "1st-level", - "Mount", - "Animal", - "Comics", - "Superhero", - "creatures", - "Hunter", - "Control", - "Dragon Ball", - "Dragon Ball Z", - "Dagger", - "questingforamonster", - "ICRPG", - "Booklet", - "f and t", - "common", - "Chaos", - "spellblade", - "Constitution", - "artisan", - "arcane", - "Released", - "ring", - "runes", - "gun", - "Supportive Material", - "The Witcher", - "Desarmado", - "Monster Monday", - "Bleach", - "Demon Slayer", - "mice", - "worldbuilding", - "Necrotic", - "ability score", - "demon", - "Armybook Shivatiano", - "warrior", - "Fighter Subclass", - "system", - "whisperveil", - "psychic", - "warhammer", - "Aventura", - "Culture", - "Material", - "meta:npc", - "shops", - "magic weapon", - "nhera", - "Dark Fantasy", - "Regles", - "Wonderous Item", - "Features", - "pokemon", - "Ghosts of Saltmarsh", - "monstrosity", - "DL TWW", - "companion", - "alternate layout", - "Tutorials", - "Kitsune", - "don", - "heroique", - "mini campaign", - "drago", - "Aquatic", - "tool", - "handmade", - "released", - "Spellblade", - "pregen", - "level 2", - "Baldurs gate 3", - "My Hero", - "Technically a subclass", - "5.24e Remastered Subclasses", - "dinosaurs", - "5E.2024", - "Razas", - "Horizon", - "Clothing", - "+2", - "castellano", - "pentacle prophecy", - "tag:Spells", - "gruppo A", - "Rpg", - "razze", - "type:Adventure", - "unfinished", - "3.5", - "gunslinger", - "BBEG", - "Arcane", - "component", - "Bow", - "backstory", - "phandalin", - "Skills", - "Pact", - "Elemental Earth", - "Joke", - "invocation", - "martial class", - "Super Villain", - "Eldritch", - "Elemental Fire", - "Homebrew Class", - "eldritch", - "cyberpunk", - "Player Race", - "Class Mod", - "Heatcoast", - "meta:Guide", - "Yemao", - "evil", - "Named NPC", - "CLASS", - "Angel", - "vecna", - "PT", - "PTBR", - "Ancient", - "Small", - "WotC Style", - "5e Homebrew", - "1st Level", - "dagger", - "Brancalonia", - "encounter", - "cat", - "primal path", - "Ambientazione", - "Magie", - "candlekeep", - "Ongoing", - "Oneshot", - "Wondrous", - "Janbrewery", - "Tattoos", - "5e (2014)", - "concentration", - "very rare", - "Set", - "Kobold", - "martial archetype", - "God", - "blog", - "New Gate", - "Healing", - "OneDnD", - "Incantesimi", - "Player Options", - "contest", - "pirate", - "Manuel", - "Alchimie", - "Herboristerie", - "Ingredients", - "starlost", - "Campaign 1", - "Abandoned", - "Previous Editions", - "Enchantment", - "Tools", - "Oblivion", - "domain", - "5th Level", - "DnD Beyond", - "Reference", - "Sorcerer Subclass", - "Dragon Magazine", - "feature", - "german", - "conjuration", - "strixhaven", - "Sentient", - "JJK", - "10 Generations", - "character creation", - "LevelUp", - "pallid grove", - "primer", - "Requires Attunement", - "College", - "Aesthetic", - "critter", - "home game", - "spanish", - "stats", - "Lairon", - "Hunters Guild", - "original setting", - "Bosses", - "Radiant Citadel", - "actions", - "Reworked", - "Elystera", - "Wyvern", - "vikings", - "thief", - "enemies", - "Obsession", - "Yi Sang", - "aberrazione", - "Limbus", - "animals", - "minecraft", - "mice of legend", - "osric", - "20 Minutes Till Dawn", - "campaign frame", - "latigo", - "DH", - "Eldritch Invocation", - "system:daggerheart", - "100ni", - "meta:Sheet", - "fa-solid fa-sheet-plastic:Ficha", - "tag:Berean", - "AD&D", - "B/X", - "The Codex Of Anomalous Entities", - "monster manual", - "Polar Waters", - "CR 12", - "CR 10", - "blood magic", - "Gunslinger", - "grimoire", - "Drakes", - "Japanese", - "subrace", - "ooze", - "Stats", - "Half Caster", - "Sea", - "time", - "Brawler", - "Session 0", - "Halloween", - "Runeterra", - "Divine", - "Random", - "Lifestar", - "arcane trickster", - "Paddy4530", - "evocation", - "light", - "Steampunk", - "shaman", - "Primal Path", - "monk subclass", - "Full Caster", - "World", - "Planning", - "spirit", - "Nova Era", - "abjuration", - "Christmas", - "Critical Role", - "Gish", - "Bandit", - "Monster Manual", - "party member", - "mgazt", - "Playable Race", - "Donjon.bin.sh", - "Final Fantasy", - "Roleplay", - "monstre", - "fairy", - "frame", - "Minecraft", - "Stealth", - "Manual", - "half caster", - "Storm", - "Sorcery", - "format work", - "Kingdom Hearts", - "hexblade", - "block", - "page layouts", - "Monk Subclass", - "FinyaFluKaiKolja", - "Radiant", - "group:playtest", - "Korrahir", - "noble", - "exorcist", - "xapien", - "Raven Queen", - "markdown", - "damage", - "Alchemy", - "morrigan", - "genasi", - "ZNH", - "folklore", - "Fate", - "hechicero", - "Air", - "Magic Weapon", - "Anime DND 5e", - "Dragon Ball Z TTRPG", - "Dragon Ball Z RPG", - "Dragon Ball Z DND", - "Dragon Ball Z 5e", - "samurai", - "Goblin", - "Base Sheet", - "Shackled City Adventure Path", - "Natureza", - "control", - "Normarch", - "Reddit", - "Genshin Impact", - "Abjuration", - "Myr", - "Flight", - "Vampyre", - "nightmare", - "Lycan", - "Occult", - "circle", - "Christmas Special", - "DoDD", - "Character Options", - "traduction", - "Characters", - "Gear", - "system:sf2e", - "drakkenheim", - "downtime", - "amulet", - "Feiticeiros e Maldicoes", - "Tecnica amaldicoada", - "prorpg", - "enemy", - "No Mercy", - "rain world", - "slugcat", - "fly", - "meta:User Guide", - "Fallout TTRPG", - "regles", - "Ill Tides", - "Light-hearted", - "Vastria", - "school", - "Fillible Online", - "Mezgarr", - "Berserk", - "invocations", - "Classe Refeita", - "Auroboros", - "bosses", - "fabula ultima", - "Shagya", - "wild", - "DnD 2024", - "KaiburrKathHound", - "Barbarian Path", - "fauna", - "5E.2014", - "system:curse of strahd", - "Unofficial", - "how to", - "Glaive", - "A5E", - "pt", - "Consumible", - "Realmers'", - "Versatile Lineage", - "Shichibukai", - "2024e", - "Rencontre", - "tag:Spell List", - "elementalist", - "noncaster", - "blasphemous", - "Mordhiem", - "Wildfrost", - "#Regelwerk", - "Rewrite", - "Maldición de Strahd", - "Scion", - "Entities", - "Hoarwyrm", - "Player utility", - "CR 1/4", - "Temperate Forest", - "Demons", - "Drow", - "type:rules", - "fay", - "2e", - "familier", - "supplement", - "Amberwar", - "slime", - "Lycanthropy", - "meta: Terres de Leyt", - "Strong", - "AAH Vol. 1", - "Force", - "Jump", - "Aboleths", - "lol", - "location", - "small", - "customizable", - "Modern", - "Sky", - "portugues", - "Hero", - "Villain", - "element", - "Tyranny of Dragons", - "Adventure Guide", - "New Class", - "Witchlight", - "Shardblade", - "Plateaux", - "WOTC", - "Snippet", - "Terra", - "Otherworldly Patron", - "ritual", - "hag", - "Cyberpunk 2077", - "tavern", - "Artificer Specialist", - "Werewolf", - "Boesia", - "vampiric", - "monastic tradition", - "Gothic", - "celestial", - "Unfinished", - "Core", - "Arcane Tradition", - "Troll", - "Origin", - "Draconic", - "dj9 member", - "test", - "Hag", - "gem", - "Invocations", - "Dark Sun", - "aarkhen", - "How to", - "ravenloft", - "faerie", - "Playtest", - "Shaman", - "dead", - "Tomba Aniquilacio", - "Pacto", - "fullcaster", - "Electric", - "Ability Score", - "4D", - "pathfinder", - "insect", - "hook", - "page layout", - "healing", - "Lineages", - "Flying", - "Martial Arts", - "journal", - "Aide de jeu", - "hunter", - "headers", - "Dark Souls", - "courtyard", - "crossroads", - "Quest", - "CotF", - "defense", - "Semryss", - "invoked class", - "Session Notes", - "goblin", - "infernal", - "fate", - "oni", - "spellbook", - "Summoning", - "slut", - "whore", - "Greyhawk", - "Mobility", - "Reddit Remake", - "Guild", - "Cosmic Mart", - "7th Level", - "dragonborn", - "curse of strahd", - "Ranger Subclass", - "dossier", - "dossie", - "de", - "pnpde", - "Plane Shift", - "halloween", - "group:aventura", - "9th Level", - "tome", - "cold", - "acid", - "deprecated", - "mind flayer", - "MECHA", - "EssentialsKit", - "2d6", - "ToD", - "Work In Progress", - "Bond", - "Versatile", - "Dead", - "SYWTBAGM", - "summoning", - "english", - "Eilistraee", - "Draft", - "DoD", - "map", - "Frightened", - "Psychic Damage", - "eberron", - "recompensa", - "wizard subclass", - "teiran", - "Saltmarsh", - "jp setting", - "Illithid", - "Longbow", - "hell", - "Monarch", - "type:feat", - "reglas", - "cooking", - "Abenteuer", - "reloaded", - "incompleto", - "mecanica", - "Location", - "Grimlores Grimoire", - "2024 Subclass", - "Chiesa di Toleno", - "finalfantasy", - "The Undertomes", - "Lobotomy Corporation", - "SDHTA", - "D&D 2024", - "other", - "ally", - "images", - "Player's Guide", - "Avalon Sword", - "Cael'Yuu", - "dnd-2014", - "Regelwerk", - "Español", - "br", - "dnd 5.0", - "monstro", - "grand cemetery", - "Phoenix", - "dnd 2024", - "Bloodhunter", - "Sintonizacion", - "dungeons & dragons", - "Fix", - "Rulebook", - "Shadowdark", - "heroic", - "HFW", - "Earthdawn", - "24e", - "cormyr", - "suzail", - "dc20", - "tag:Rules", - "The Griffon's Saddlebag", - "LOTM", - "tag:Adventure", - "drunken master", - "eldritch invocation", - "Персонаж", - "Orcs", - "Lizardfolk", - "Frostfell", - "CR 17", - "Shapechanger", - "Farmland", - "Mages", - "Any", - "CR 13", - "Earth", - "Mountain", - "Drake", - "transformation", - "GM", - "Lich", - "lovecraft", - "unique", - "Optional Rules", - "int", - "creator", - "Primal", - "simple", - "golem", - "Void", - "Armour", - "spellsword", - "General", - "Asian", - "Bringers of chaos", - "Optional Feature", - "subraces", - "Galanoth", - "barbarian subclass", - "felhearth", - "modular", - "Vampires", - "wysteria", - "adaptation", - "beasts", - "naruto", - "ninja", - "Psionic", - "Guns", - "Crystal", - "Guardian", - "NonProfit", - "Mimic", - "languages", - "Epic Boons", - "Primer", - "Icewind Dale", - "joke", - "lycan", - "CR3", - "Armors", - "ff7", - "materia", - "final fantasy 7 remake", - "esper", - "ff7 remake", - "gargantuan", - "Frog", - "CR5", - "blank", - "monster hunter", - "league of legends", - "french", - "Pokémon", - "kobold", - "soul", - "ffxi", - "d10", - "Roman", - "Cute", - "DD5", - "variant", - "tree", - "fr", - "Scenario", - "lycanthrope", - "druide", - "staff", - "eios", - "arkheneios", - "Runic", - "Work", - "Ukrainian", - "cover-page", - "mage", - "deities", - "gods", - "Boss Fight", - "Lair", - "WBTW", - "roguish archetype", - "Character Option", - "Shortsword", - "Illrigger", - "Bloodborne", - "cr6", - "Priest", - "Hamon", - "Toonkind", - "rol", - "Strength", - "forgotten realms", - "Spanish", - "Conclave", - "Electro", - "Magical Tattoos", - "Matt Mercer", - "Wildemount", - "Mighty Nien", - "Campaign 2", - "Resistances", - "Bug", - "impression", - "PF", - "Magnus Archives", - "ice", - "speed", - "Generic NPC", - "Titanic", - "Ink Friendly", - "bleed", - "elder scrolls", - "Immortal", - "LMOP", - "Travel", - "Olphus", - "3d6", - "heist", - "World History", - "ghost", - "genie", - "kids on bikes", - "Russia", - "conclave", - "overhaul", - "manual", - "Adventures In Eden", - "Downtime", - "hamon", - "cloak", - "shadowfell", - "Hellfire", - "Paladin Oath", - "Genshin", - "Nation", - "air", - "Magical Item", - "War", - "Original", - "Monstrous Compendium", - "Calamity", - "Warden", - "Apocalypse", - "shield", - "AC", - "expansion", - "Concentration", - "charm", - "Weave", - "lycanthropy", - "raza", - "far realm", - "fighter subclass", - "ita", - "Pirate", - "Laranja", - "Grapple", - "EastByForce", - "hobgoblin", - "oneshot-notes", - "Holy", - "optional", - "type:cenario", - "group:core", - "The Brewery", - "Alcance", - "Morrowind", - "Indigo", - "Divino", - "2nd Level", - "Sub-Class", - "cantrips", - "Cloak", - "battle master", - "Dark", - "Puzzle", - "Lucky", - "consumable", - "rebalance", - "Shove", - "Area Control", - "Vanguard", - "funny", - "e5", - "Dragonlance", - "psion", - "initiative", - "Tactician", - "Inspiration", - "artificier", - "way", - "inspired", - "historia", - "Medusa", - "2 part", - "holy", - "gift", - "Nimble", - "mostri", - "phoenix", - "travel", - "Class Template", - "Intimidation", - "constructs", - "P666", - "Formatting", - "Divinity", - "Rod", - "Language", - "yokai", - "rune", - "western", - "vampires", - "flying", - "cute", - "Enemy", - "boon", - "Tables", - "ShadowFight", - "meta: Theme", - "SCS", - "vanthampur villa", - "CoA", - "shop", - "destiny", - "magical weapon", - "Arcane Arcade", - "XP to Level 3", - "Dice Average RPG", - "Pip-Boy", - "Dragon Heist", - "session notes", - "tattoo", - "flick", - "P6:66", - "Comic Character", - "experiment", - "Minerva", - "type:Spellbook", - "Realmfall", - "Wand", - "halfling", - "sw5e", - "implementar AP", - "Mask", - "Gazook89", - "Weltenrauch-Chroniken", - "MiA", - "Made in Abyss", - "français", - "fae", - "Lemuria", - "Mork Borg", - "guerrier", - "prunus", - "condition", - "pf2", - "tr", - "costrutto", - "German", - "project moon", - "5r", - "galles", - "Project moon", - "Yisang", - "Spicebush", - "player-accessible", - "Especie", - "Westmarch", - "a", - "Cart", - "Magus", - "group:Mchael Galvis", - "tip", - "werewolf", - "mundane", - "garrett", - "unarmed", - "Arcane Odyssey", - "Tomb of Divinity", - "pets", - "Video Game", - "4 part", - "pbta", - "Druids", - "multiclass", - "manuale", - "mimic", - "plane shift", - "Dotes", - "Hechizos", - "Infernal", - "Enhanced", - "done", - "Mission report", - "Blanks", - "Masks", - "Ultimate Ability", - "shadow-slave", - "Advertising", - "transform", - "Fullmetal Alchemist", - "Fullmetal Alchemist Brotherhood", - "tag:TAoF&F", - "Dwarves", - "Humans", - "Nine Hells", - "Devils", - "Archons", - "CR 15", - "Troglodytes", - "Goliath", - "retired", - "boots", - "ranged", - "shields", - "Zhentarim", - "World of Warcraft", - "Frontline", - "Guildmaster's Guide to Ravnica", - "Dungeons & Dragons 5e", - "beholder", - "NEEDS FIXING", - "mechanic", - "Loot", - "champion", - "Runes", - "Shield", - "Punch", - "Sniper", - "Magical Girl", - "NotDND", - "story", - "Sleep", - "Bard College", - "Illusion", - "Thunder", - "Defender", - "Genasi", - "troll", - "Gehenna", - "Yugoloth", - "social", - "Player Class", - "homebrew class", - "CR 16", - "Ghost", - "Kobolds", - "Trolls", - "Yuan-Ti", - "Elder Scrolls Offline", - "armure", - "Mage", - "CR 18", - "Technology", - "Mystery", - "darkness", - "Airship", - "New Campaign", - "Warframe", - "Wizard Subclass", - "Gold", - "Candor", - "Overhaul", - "Dragon Knight", - "Enoreth", - "Artifacts", - "New", - "AMMO", - "Campagne", - "Valbise", - "Subclasseptember", - "Mecha", - "Yu-Gi-Oh", - "Goblinoid", - "underwater", - "SW5E", - "bardo" -] \ No newline at end of file + 'meta:Theme', + '5e', + 'Subclass', + 'meta:theme', + 'subclass', + 'Class', + 'Homebrew', + 'Race', + 'Dungeons and Dragons', + 'theme', + 'Daggerheart', + '2024', + 'One Piece', + 'One Piece DND', + 'Luffy', + 'Dungeons and Devil Fruits', + 'Strawhats', + 'Template', + 'Campaign Frame', + 'class', + 'Players Handbook', + 'dnd', + 'osr', + 'Dungeon Masters Guide', + 'shadowdark', + 'dragonbane', + 'PHB', + 'example', + 'Devil Fruits', + 'system:pf2e', + 'DnD', + 'DMG', + 'system:dnd5.5', + 'Monster', + 'homebrew', + 'race', + 'template', + 'Warlock', + 'monster', + 'Fighter', + 'warlock', + 'druid', + 'sorcerer', + 'D&D', + 'Magic Item', + 'Barbarian', + 'Artificer', + '2014', + 'system:descent into avernus', + 'Sorcerer', + 'Adventure', + 'Paladin', + 'Ranger', + 'user help', + 'fighter', + '5th Edition', + 'Spells', + 'Monk', + 'Spell', + 'NPC', + 'Cleric', + 'spell', + 'Rogue', + 'css', + 'Item', + 'artificer', + 'magic item', + 'Rules', + 'barbarian', + 'wizard', + 'russian', + 'DnD5e', + 'Wizard', + 'paladin', + 'bastionland', + 'spells', + 'Devil Fruit', + 'Bard', + '5.5e', + 'rogue', + 'Tabletop System', + 'Haki', + 'Druid', + 'mystic bastionland', + 'item', + 'Lore', + 'bard', + 'monk', + 'system:dnd5e', + 'world', + 'ranger', + 'WIP', + 'cleric', + 'Dragon', + 'Naruto', + 'Creature', + 'snippet', + 'npc', + 'DeS', + 'Magic', + 'guide', + 'v3', + 'Beast', + 'Classe', + 'onering', + 'Monsters', + 'Races', + 'Weapon', + 'adventure', + 'Subclasses', + 'stat block', + 'weapon', + 'Species', + 'DONE', + 'archetype', + 'RPG', + 'Hollow Knight', + '5e\'24', + 'Martial', + 'DND', + 'Classe Nova', + 'Curse of Strahd', + 'Boss', + 'Hollowed Kingdoms', + 'baldurs mouth', + '5.24', + 'Homewbrew', + 'Encyclopedia', + 'Revised', + 'OneWorldHD', + 'knight', + 'DPS', + 'srd', + 'Undead', + 'items', + 'DnD 5e', + 'Guide', + 'Compendium', + 'Feat', + 'newspaper', + 'magic', + 'TTRPG', + 'descent into avernus', + 'reference', + 'system:D&D 5e24', + 'feat', + 'Magic Items', + 'Campaign', + 'resource', + 'Feats', + 'Anime', + 'dd5', + 'races', + 'Monstrosity', + 'DM Screen', + '2024 Rules', + 'Rework', + 'Character Build', + 'Done', + '5e 2024', + 'Construct', + 'myth', + 'magic items', + 'creature', + 'Legendary', + 'Strahd', + 'background', + 'Player', + 'style', + 'Legacy', + 'Player Handbook', + 'martial', + 'Character', + 'Dungeons & Dragons', + 'Table', + 'reddit', + 'monsters', + 'OneDND', + 'dragon', + 'Suporte', + 'Soulbound', + 'Expanded Handbook', + 'bestiary', + 'Humanoid', + 'system:dnd', + 'Oredell', + 'system:class', + 'V3', + 'system:5e', + '5e\'14', + 'Age of Sigmar', + 'Items', + 'Eberron', + 'horror', + 'dnd5e', + 'star wars', + 'Background', + 'compendium', + 'revision', + 'Elemental', + 'character', + 'Marcial', + 'SW5e', + 'notes', + 'DM', + 'Fey', + 'one-shot', + 'resources', + 'NEW', + 'campaign', + 'wondrous item', + 'Setting', + 'Archive', + 'NIMRE', + 'Tanque', + 'Jogavel', + 'Dnd 5e', + 'LotM', + 'setting', + 'revised', + 'Warhammer', + 'rework', + 'Conjurador', + 'GMBinder', + 'ItemSet', + 'NPCs', + 'classes', + 'CR 2', + 'AetherSail', + 'undead', + 'Artifact', + 'cards', + 'Example', + 'Guides', + 'Theme', + 'Swamp', + 'CR 1', + 'patron', + 'Extra', + 'concept', + 'final fantasy', + 'Aberration', + 'Elder Scrolls', + 'rules', + 'meta:gratis', + 'Dice Pool', + 'Cue', + 'dark', + 'type:Style', + 'rpg', + 'meta:free', + 'summoner', + 'OC', + 'rare', + 'Fleshing Out', + 'francais', + 'Dnd', + 'Creatures', + 'Sims 4', + 'sous-classe', + 'ffxiv', + 'Underdark', + 'add-on', + 'weapons', + 'Subrace', + 'dungeons and dragons', + 'Naruto 5e', + 'Lafari', + 'Very Rare', + 'd6', + 'red', + 'Equipment', + 'CR 3', + 'Patron', + '5E', + 'objet magique', + 'spellcaster', + 'feats', + '5.24e', + 'system:d&d5e', + 'Rare', + 'Thudnfer', + 'daggerheart', + 'CR 1/2', + 'Archetype', + 'dnd 5e', + 'Pathfinder', + 'lineage', + 'Celestial', + 'Support', + 'species', + 'ARCHIVED', + 'Horror', + 'humanoid', + 'Subclase', + 'book:PHB E&E', + 'final fantasy xiv', + 'Jungle', + 'Feywild', + 'Fiend', + 'subclasses', + 'HB', + 'Legacy Challenge', + 'Project Horizon', + 'vampire', + 'WoW', + 'DND 5e', + 'Weapons', + 'system:book clone', + 'CoS', + 'N5e', + 'Summon', + 'Spellcaster', + 'Koretra', + 'Voidborn', + 'one shot', + 'Templates', + 'tables', + 'Iphexar', + 'Shattered Obelisk', + 'Sword Coast', + 'elemental', + 'lore', + 'character sheet', + 'discord', + 'BetterMonsters', + 'players', + 'group:simple skans', + 'Coastal', + 'Forest', + 'Unearthed Arcana', + 'Old', + 'Collection', + 'Ancestry', + 'Caevash', + 'Strixhaven', + 'Limbus Company', + 'Daydreams & Deviants', + 'Statblocks', + 'Urban', + 'Classes', + 'familiar', + 'Blood', + 'oneshot', + 'n5e', + 'wip', + 'masks', + 'Planeshifted', + 'Carrioss', + 'avernus', + 'object', + '1', + 'Ruins', + 'Anime Character', + 'wild shape', + 'mask', + 'dj9 game', + 'Handbook', + 'Curse', + 'oath', + 'Midralis', + 'Appendix', + '5.5', + 'tales of the valiant', + 'player classes', + 'Caster', + 'Large', + 'Fateforge', + 'Cursed', + 'beast', + 'Pathfinder 2e', + 'Design', + 'Uncommon', + 'Endeur', + 'Elemental Water', + 'SCC', + 'sci-fi', + 'Dragons', + 'human', + 'Gods', + 'Medium', + 'System', + 'Help', + 'Handout', + 'Skyrim', + 'BnB', + 'draft', + 'PC', + 'Variant', + 'syntax', + 'OneShot', + 'Clase', + 'UESTRPG', + 'Savannah', + 'Reef', + 'CR 5', + 'Forgotten Realms', + 'collection', + 'Combat', + 'Historia', + 'artifact', + 'Expansion', + 'Attunement', + 'Variant Rules', + 'd&d', + 'Party Build', + 'Evocation', + 'homerule', + 'Forbidden West', + 'how-to', + 'tov', + 'Mystical Item', + 'CR 4', + 'Necromancer', + 'General Rules', + 'Needs Update', + 'stat blocks', + 'DC Comics', + 'Sword', + 'Armor', + 'blood hunter', + 'Blood Hunter', + 'Meio Conjurador', + 'Mydia', + '3rd Party', + 'N5E', + 'Delvebound', + 'Ocean', + 'Subterranean', + 'half-caster', + 'Demon', + 'Fire', + 'meta:Template', + 'Character Sheet', + 'PF2e', + 'png', + 'fantasy', + 'Setting Guide', + 'Style', + 'Cor', + 'legacy', + 'Minion', + 'meta:khaoz age', + 'Book', + 'magical item', + 'immersion', + 'reminder cards', + 'Regras', + 'Durnovar', + '2025', + 'Camp1', + 'Abyss', + 'armor', + 'construct', + 'firearms', + 'Backgrounds', + 'Companion', + 'Melee', + 'fey', + 'Incomplete', + 'Vampire', + 'Bestiary', + 'Worldbuilding', + 'History', + 'Conjuration', + 'necromancy', + 'dragons', + 'ancestry', + 'Mech', + 'PbtA', + 'COS', + 'One Shot', + 'Factions', + 'Transmutation', + 'Spellcasting', + 'card', + 'Ardh', + 'redveil', + 'conditions', + 'elturel', + 'rhye', + 'group:James Haeck', + 'CaelYuu', + 'system:5.24e', + 'system:GM Binder', + 'Grassland', + 'melee', + 'Potions', + 'anime', + 'D&D 5e', + 'Healer', + 'Gambling', + 'Lightning', + 'fighting style', + 'support', + 'Style Template', + 'mtg', + 'NSFW', + 'aventura', + 'Manuals', + 'plant', + 'Incarnate', + 'Crafting', + 'DnDBeyond', + 'Monster Girl', + 'Monster Girl Encyclopedia', + 'pet', + 'npcs', + 'Stat Block', + 'Styleguide', + 'mitologia', + 'Objeto maravilloso', + 'vaesen rpg', + 'dnd-2024', + 'Class Handbook', + 'Space', + 'Taiga', + 'CR 6', + 'Pact Boon', + 'race/ancestry', + 'Necromancy', + 'cantrip', + 'LoL', + 'Raza', + 'handout', + 'Mechanic', + 'Conversion', + 'Wondrous Item', + 'Familiar', + 'necromancer', + 'uncommon', + 'curse', + 'Campaign Setting', + 'Tetra', + '1e', + 'module', + 'Evolving', + 'boiling sea', + 'deck', + 'OSR', + 'RU', + 'VL', + 'Underdeep', + 'Deep Ocean', + 'Giant', + 'statblock', + 'combat', + 'Time', + '5E24', + 'session zero', + 'elf', + 'tank', + 'sorcerous origin', + 'Drakkenheim', + 'Tavern', + 'Domain', + 'healer', + 'Valenor', + 'blood', + 'Oath', + 'spooky', + 'fire', + 'meta:5e24 Style', + 'Notes', + 'City', + 'Conjurador Completo', + 'prop', + 'Dotherys', + 'Rietuma 3.0', + '5e24', + 'Library of Ruina', + 'español', + 'Project Echo', + 'battle of Japan', + 'Plant', + 'Badlands', + 'Neverwinter', + 'Fantasy', + 'Beastfolk', + 'Unarmed', + 'Cold', + 'Damage', + 'attunement', + 'Hurthud', + '3rd Level', + 'spelljammer', + 'mostro', + 'Custom', + 'PT-BR', + 'Alternative Realms', + 'The Foot', + 'boss', + 'demo', + 'Supplement', + 'FitD', + 'classe', + '5.14', + 'Copy', + 'DnD5e24', + 'X-Men', + 'TNA', + 'CR 8', + 'Desert', + 'CR 7', + 'arme', + 'random', + 'spellcasting', + 'Deprecated', + 'Cards', + 'finished', + 'Ben 10', + 'equipment', + 'Geography', + 'Games', + 'For Players', + 'Faerun', + 'scroll', + 'Faction', + 'Alchemist', + 'drow', + 'Lineage', + 'mix-blend-mode', + 'columns', + 'User Help', + 'Reami Dimenticati', + 'Класс', + 'D100', + 'nsfw', + 'hucaen', + 'v1.0', + 'Cortex', + 'Fallout', + 'ww5e', + 'MAGIC', + 'DnD2024', + 'ToV', + 'D&D2024', + 'The Backrooms', + 'Freshwater', + 'D20', + 'Dragonborn', + 'custom', + 'sword', + 'Dungeons and Dragons 5e', + 'Water', + 'legendary', + 'Dungeon', + 'Ravenloft', + 'aberration', + 'Longsword', + 'transmutation', + 'Fairy Tail', + 'Character background', + 'Exandria', + 'Updated', + 'pitch', + 'Half-Caster', + 'Complete', + 'Money', + 'player', + 'forgotten-realms', + 'Festival', + 'Casino', + 'SCAG', + 'Currency', + 'North', + 'Toril', + 'Scourged Land of Valenor', + 'Oota', + 'parchment', + 'Literature', + 'Serrith', + 'PNJ', + 'Divinity Original Sin 2', + 'Wild', + 'videogame', + 'magic the gathering', + 'sweetblossom', + 'GMscreen', + 'MandM', + 'D&D 5.24', + 'Camp2', + 'Remaster', + 'riassunti', + 'type:Resource', + 'system:D&D', + 'tag:Class', + 'Excelsior', + 'Stat Blocks', + 'Sci-Fi', + 'Ooze', + 'CR 1/8', + 'sublclass', + 'chart', + 'Mountains', + 'guns', + 'Nature', + 'Orc', + 'Poison', + 'Devil', + 'fiend', + 'DC', + 'pt-br', + 'ABnB', + 'One-Shot', + 'strahd', + 'Ring', + 'Theme song', + 'orc', + 'summon', + 'Psion', + 'Psionics', + 'Dungeon Master', + 'vehicle', + 'DM only', + 'Demigod', + 'Antica Energia', + 'Pirates', + 'Sourcebook', + 'devil', + 'Cantrip', + 'mystery', + 'MtG', + 'conversion', + 'Festivals', + 'Casinos', + 'Taverns', + 'Betting', + 'Drinking', + 'phandelver', + 'Warhammer 40k', + 'mutant', + 'styling', + 'FATE', + 'Lone Wolf', + 'icon', + 'New Dawn', + 'Magic Set', + 'Paladin Subclass', + 'Alter Class', + 'difficulty classses', + 'combat tables', + 'phb', + 'Project Moon', + 'Undertomes', + 'EGO', + 'Campagne 1', + 'Constelação', + 'Arvore I', + 'Fim da Jornada', + 'greek god', + 'dwarf', + 'Firearms', + '3.5e', + 'generator', + 'Elf', + 'meta: Scenario', + 'enchantment', + 'buff', + 'ITW', + 'Tank', + 'Archived', + 'Martial Archetype', + 'caster', + 'BR', + 'Knight', + 'Utility', + 'SWADE', + 'Star Wars', + 'pc', + 'Mystic', + 'Useful', + 'Netherdeep', + 'crafting', + 'Sapient Undead', + 'Maverick', + 'Revision', + 'Resource', + 'Humblewood', + 'one piece', + 'Bag of Holding', + 'medium', + 'lightning', + 'backgrounds', + '4th Level', + 'path', + 'BREAK-RPG', + 'dark fantasy', + 'Players', + 'poison', + 'psionic', + 'gazook89', + 'homebrew subclass', + 'wild-wasteland', + 'CWD', + 'Paid', + 'Tales of the Valiant', + 'Dreadhold', + 'arma', + 'system:Mutants and Masterminds', + '#Tiefschlaf', + 'Brew', + 'Myra', + 'Swashbuckler', + 'dead by daylight', + 'Exceptional', + 'COD Zombies', + 'Hills', + 'Tundra', + 'type:Campaign', + 'wild magic', + 'Food', + 'Death', + 'homebrew rules', + 'Remake', + 'Witcher', + 'water', + 'Pet', + 'book', + 'AAH', + 'pact', + 'Ice', + 'Character Creation', + 'animal', + 'Pokemon', + 'clase', + '5e14', + 'DBZ', + 'CLONE', + 'Evil', + 'Tarsere', + 'Mythology', + 'pf2e', + 'Magical', + 'type:race', + 'Sorcerous Origin', + 'Information', + 'styles', + 'Module', + 'gish', + 'frames', + 'DeltaGreen', + 'Magic item', + 'food', + 'chef', + 'basics', + 'giant', + 'Brew Creation', + 'One-shot', + 'ttrpg', + 'Path', + 'Don\'t Starve', + 'MGE', + 'firearm', + 'DnDBehindTheScreen', + 'store', + 'The Artisan', + 'timeline', + 'college', + 'dev', + 'dungeon of the dead three', + 'Cradle', + 'Dnd5e', + 'dungeon', + 'Amaranthine', + 'Regno di Oltremare', + 'bestia', + 'rewrite', + 'WiP', + 'Subclasse', + 'mutants and masterminds', + 'The Embrace', + 'meta:documentation', + 'Mutants And Masterminds', + 'khedoria', + 'Encounter Pack', + 'giorni', + 'Statblock', + 'Enemies', + 'Goblinoids', + 'Heavens', + 'system:2e', + 'Vaalbara', + 'Dwarf', + 'airos', + 'table', + 'Artificer Specialization', + 'Buff', + 'Book 1', + 'Ranged', + 'cypher', + 'utilities', + '40k', + 'Psychic', + 'Fear', + 'steampunk', + 'shadow', + 'subclase', + 'Barbarian Subclass', + 'Elements', + 'pact boon', + 'Clan', + 'Fly', + 'solo', + 'sourcebook', + 'Marvel Comics', + 'compilation', + 'Firearm', + 'sidekick', + 'infusions', + 'Mechanics', + 'Summoner', + 'Aasimar', + 'Human', + 'Vehicle', + 'Shadow', + 'Clone', + 'custom css', + 'ocean', + 'sotdl', + 'bandit', + 'Wind', + 'Printer Friendly', + 'Obsolete', + 'mechanics', + 'illusion', + '5th edition', + 'League of Legends', + 'Vestige', + 'dungeons', + 'Dungeons', + 'and', + 'Elden Ring', + 'L5R', + 'd20', + 'Poisons', + 'd15', + 'Dungeons And Dragons', + 'MTG', + 'divine', + 'characters', + 'witch', + 'Anime Homebrew', + 'Zombie', + 'thunder', + 'Jujutsu Kaisen', + 'campagne', + 'Deadlands', + 'spell list', + '1 Person', + 'Ritual', + 'screen', + 'nature', + 'Divination', + 'Compattare', + 'dtrpg', + 'quick ref', + 'Mago', + 'Illivia', + 'Shonen', + 'Core Deities', + 'green ronin', + 'Bless', + 'D&D5e', + 'version:0.1.0', + 'curato', + 'system:Ord', + 'Images', + 'Sealed Artifact', + 'Giants', + 'CR 9', + 'CR 11', + 'CR 0', + 'CR 14', + 'Shadowfell', + 'Tier 1', + 'd100', + 'Elemental Air', + 'artificiel', + 'Cultist', + 'Cyberpunk', + 'Huge', + 'Warrior', + 'Gun', + 'quest', + 'LYRA', + 'Music', + 'Tiefling', + 'Master', + 'Witch', + 'Linnorm', + '1st-level', + 'Mount', + 'Animal', + 'Comics', + 'Superhero', + 'creatures', + 'Hunter', + 'Control', + 'Dragon Ball', + 'Dragon Ball Z', + 'Dagger', + 'questingforamonster', + 'ICRPG', + 'Booklet', + 'f and t', + 'common', + 'Chaos', + 'spellblade', + 'Constitution', + 'artisan', + 'arcane', + 'Released', + 'ring', + 'runes', + 'gun', + 'Supportive Material', + 'The Witcher', + 'Desarmado', + 'Monster Monday', + 'Bleach', + 'Demon Slayer', + 'mice', + 'worldbuilding', + 'Necrotic', + 'ability score', + 'demon', + 'Armybook Shivatiano', + 'warrior', + 'Fighter Subclass', + 'system', + 'whisperveil', + 'psychic', + 'warhammer', + 'Aventura', + 'Culture', + 'Material', + 'meta:npc', + 'shops', + 'magic weapon', + 'nhera', + 'Dark Fantasy', + 'Regles', + 'Wonderous Item', + 'Features', + 'pokemon', + 'Ghosts of Saltmarsh', + 'monstrosity', + 'DL TWW', + 'companion', + 'alternate layout', + 'Tutorials', + 'Kitsune', + 'don', + 'heroique', + 'mini campaign', + 'drago', + 'Aquatic', + 'tool', + 'handmade', + 'released', + 'Spellblade', + 'pregen', + 'level 2', + 'Baldurs gate 3', + 'My Hero', + 'Technically a subclass', + '5.24e Remastered Subclasses', + 'dinosaurs', + '5E.2024', + 'Razas', + 'Horizon', + 'Clothing', + '+2', + 'castellano', + 'pentacle prophecy', + 'tag:Spells', + 'gruppo A', + 'Rpg', + 'razze', + 'type:Adventure', + 'unfinished', + '3.5', + 'gunslinger', + 'BBEG', + 'Arcane', + 'component', + 'Bow', + 'backstory', + 'phandalin', + 'Skills', + 'Pact', + 'Elemental Earth', + 'Joke', + 'invocation', + 'martial class', + 'Super Villain', + 'Eldritch', + 'Elemental Fire', + 'Homebrew Class', + 'eldritch', + 'cyberpunk', + 'Player Race', + 'Class Mod', + 'Heatcoast', + 'meta:Guide', + 'Yemao', + 'evil', + 'Named NPC', + 'CLASS', + 'Angel', + 'vecna', + 'PT', + 'PTBR', + 'Ancient', + 'Small', + 'WotC Style', + '5e Homebrew', + '1st Level', + 'dagger', + 'Brancalonia', + 'encounter', + 'cat', + 'primal path', + 'Ambientazione', + 'Magie', + 'candlekeep', + 'Ongoing', + 'Oneshot', + 'Wondrous', + 'Janbrewery', + 'Tattoos', + '5e (2014)', + 'concentration', + 'very rare', + 'Set', + 'Kobold', + 'martial archetype', + 'God', + 'blog', + 'New Gate', + 'Healing', + 'OneDnD', + 'Incantesimi', + 'Player Options', + 'contest', + 'pirate', + 'Manuel', + 'Alchimie', + 'Herboristerie', + 'Ingredients', + 'starlost', + 'Campaign 1', + 'Abandoned', + 'Previous Editions', + 'Enchantment', + 'Tools', + 'Oblivion', + 'domain', + '5th Level', + 'DnD Beyond', + 'Reference', + 'Sorcerer Subclass', + 'Dragon Magazine', + 'feature', + 'german', + 'conjuration', + 'strixhaven', + 'Sentient', + 'JJK', + '10 Generations', + 'character creation', + 'LevelUp', + 'pallid grove', + 'primer', + 'Requires Attunement', + 'College', + 'Aesthetic', + 'critter', + 'home game', + 'spanish', + 'stats', + 'Lairon', + 'Hunters Guild', + 'original setting', + 'Bosses', + 'Radiant Citadel', + 'actions', + 'Reworked', + 'Elystera', + 'Wyvern', + 'vikings', + 'thief', + 'enemies', + 'Obsession', + 'Yi Sang', + 'aberrazione', + 'Limbus', + 'animals', + 'minecraft', + 'mice of legend', + 'osric', + '20 Minutes Till Dawn', + 'campaign frame', + 'latigo', + 'DH', + 'Eldritch Invocation', + 'system:daggerheart', + '100ni', + 'meta:Sheet', + 'fa-solid fa-sheet-plastic:Ficha', + 'tag:Berean', + 'AD&D', + 'B/X', + 'The Codex Of Anomalous Entities', + 'monster manual', + 'Polar Waters', + 'CR 12', + 'CR 10', + 'blood magic', + 'Gunslinger', + 'grimoire', + 'Drakes', + 'Japanese', + 'subrace', + 'ooze', + 'Stats', + 'Half Caster', + 'Sea', + 'time', + 'Brawler', + 'Session 0', + 'Halloween', + 'Runeterra', + 'Divine', + 'Random', + 'Lifestar', + 'arcane trickster', + 'Paddy4530', + 'evocation', + 'light', + 'Steampunk', + 'shaman', + 'Primal Path', + 'monk subclass', + 'Full Caster', + 'World', + 'Planning', + 'spirit', + 'Nova Era', + 'abjuration', + 'Christmas', + 'Critical Role', + 'Gish', + 'Bandit', + 'Monster Manual', + 'party member', + 'mgazt', + 'Playable Race', + 'Donjon.bin.sh', + 'Final Fantasy', + 'Roleplay', + 'monstre', + 'fairy', + 'frame', + 'Minecraft', + 'Stealth', + 'Manual', + 'half caster', + 'Storm', + 'Sorcery', + 'format work', + 'Kingdom Hearts', + 'hexblade', + 'block', + 'page layouts', + 'Monk Subclass', + 'FinyaFluKaiKolja', + 'Radiant', + 'group:playtest', + 'Korrahir', + 'noble', + 'exorcist', + 'xapien', + 'Raven Queen', + 'markdown', + 'damage', + 'Alchemy', + 'morrigan', + 'genasi', + 'ZNH', + 'folklore', + 'Fate', + 'hechicero', + 'Air', + 'Magic Weapon', + 'Anime DND 5e', + 'Dragon Ball Z TTRPG', + 'Dragon Ball Z RPG', + 'Dragon Ball Z DND', + 'Dragon Ball Z 5e', + 'samurai', + 'Goblin', + 'Base Sheet', + 'Shackled City Adventure Path', + 'Natureza', + 'control', + 'Normarch', + 'Reddit', + 'Genshin Impact', + 'Abjuration', + 'Myr', + 'Flight', + 'Vampyre', + 'nightmare', + 'Lycan', + 'Occult', + 'circle', + 'Christmas Special', + 'DoDD', + 'Character Options', + 'traduction', + 'Characters', + 'Gear', + 'system:sf2e', + 'drakkenheim', + 'downtime', + 'amulet', + 'Feiticeiros e Maldicoes', + 'Tecnica amaldicoada', + 'prorpg', + 'enemy', + 'No Mercy', + 'rain world', + 'slugcat', + 'fly', + 'meta:User Guide', + 'Fallout TTRPG', + 'regles', + 'Ill Tides', + 'Light-hearted', + 'Vastria', + 'school', + 'Fillible Online', + 'Mezgarr', + 'Berserk', + 'invocations', + 'Classe Refeita', + 'Auroboros', + 'bosses', + 'fabula ultima', + 'Shagya', + 'wild', + 'DnD 2024', + 'KaiburrKathHound', + 'Barbarian Path', + 'fauna', + '5E.2014', + 'system:curse of strahd', + 'Unofficial', + 'how to', + 'Glaive', + 'A5E', + 'pt', + 'Consumible', + 'Realmers\'', + 'Versatile Lineage', + 'Shichibukai', + '2024e', + 'Rencontre', + 'tag:Spell List', + 'elementalist', + 'noncaster', + 'blasphemous', + 'Mordhiem', + 'Wildfrost', + '#Regelwerk', + 'Rewrite', + 'Maldición de Strahd', + 'Scion', + 'Entities', + 'Hoarwyrm', + 'Player utility', + 'CR 1/4', + 'Temperate Forest', + 'Demons', + 'Drow', + 'type:rules', + 'fay', + '2e', + 'familier', + 'supplement', + 'Amberwar', + 'slime', + 'Lycanthropy', + 'meta: Terres de Leyt', + 'Strong', + 'AAH Vol. 1', + 'Force', + 'Jump', + 'Aboleths', + 'lol', + 'location', + 'small', + 'customizable', + 'Modern', + 'Sky', + 'portugues', + 'Hero', + 'Villain', + 'element', + 'Tyranny of Dragons', + 'Adventure Guide', + 'New Class', + 'Witchlight', + 'Shardblade', + 'Plateaux', + 'WOTC', + 'Snippet', + 'Terra', + 'Otherworldly Patron', + 'ritual', + 'hag', + 'Cyberpunk 2077', + 'tavern', + 'Artificer Specialist', + 'Werewolf', + 'Boesia', + 'vampiric', + 'monastic tradition', + 'Gothic', + 'celestial', + 'Unfinished', + 'Core', + 'Arcane Tradition', + 'Troll', + 'Origin', + 'Draconic', + 'dj9 member', + 'test', + 'Hag', + 'gem', + 'Invocations', + 'Dark Sun', + 'aarkhen', + 'How to', + 'ravenloft', + 'faerie', + 'Playtest', + 'Shaman', + 'dead', + 'Tomba Aniquilacio', + 'Pacto', + 'fullcaster', + 'Electric', + 'Ability Score', + '4D', + 'pathfinder', + 'insect', + 'hook', + 'page layout', + 'healing', + 'Lineages', + 'Flying', + 'Martial Arts', + 'journal', + 'Aide de jeu', + 'hunter', + 'headers', + 'Dark Souls', + 'courtyard', + 'crossroads', + 'Quest', + 'CotF', + 'defense', + 'Semryss', + 'invoked class', + 'Session Notes', + 'goblin', + 'infernal', + 'fate', + 'oni', + 'spellbook', + 'Summoning', + 'slut', + 'whore', + 'Greyhawk', + 'Mobility', + 'Reddit Remake', + 'Guild', + 'Cosmic Mart', + '7th Level', + 'dragonborn', + 'curse of strahd', + 'Ranger Subclass', + 'dossier', + 'dossie', + 'de', + 'pnpde', + 'Plane Shift', + 'halloween', + 'group:aventura', + '9th Level', + 'tome', + 'cold', + 'acid', + 'deprecated', + 'mind flayer', + 'MECHA', + 'EssentialsKit', + '2d6', + 'ToD', + 'Work In Progress', + 'Bond', + 'Versatile', + 'Dead', + 'SYWTBAGM', + 'summoning', + 'english', + 'Eilistraee', + 'Draft', + 'DoD', + 'map', + 'Frightened', + 'Psychic Damage', + 'eberron', + 'recompensa', + 'wizard subclass', + 'teiran', + 'Saltmarsh', + 'jp setting', + 'Illithid', + 'Longbow', + 'hell', + 'Monarch', + 'type:feat', + 'reglas', + 'cooking', + 'Abenteuer', + 'reloaded', + 'incompleto', + 'mecanica', + 'Location', + 'Grimlores Grimoire', + '2024 Subclass', + 'Chiesa di Toleno', + 'finalfantasy', + 'The Undertomes', + 'Lobotomy Corporation', + 'SDHTA', + 'D&D 2024', + 'other', + 'ally', + 'images', + 'Player\'s Guide', + 'Avalon Sword', + 'Cael\'Yuu', + 'dnd-2014', + 'Regelwerk', + 'Español', + 'br', + 'dnd 5.0', + 'monstro', + 'grand cemetery', + 'Phoenix', + 'dnd 2024', + 'Bloodhunter', + 'Sintonizacion', + 'dungeons & dragons', + 'Fix', + 'Rulebook', + 'Shadowdark', + 'heroic', + 'HFW', + 'Earthdawn', + '24e', + 'cormyr', + 'suzail', + 'dc20', + 'tag:Rules', + 'The Griffon\'s Saddlebag', + 'LOTM', + 'tag:Adventure', + 'drunken master', + 'eldritch invocation', + 'Персонаж', + 'Orcs', + 'Lizardfolk', + 'Frostfell', + 'CR 17', + 'Shapechanger', + 'Farmland', + 'Mages', + 'Any', + 'CR 13', + 'Earth', + 'Mountain', + 'Drake', + 'transformation', + 'GM', + 'Lich', + 'lovecraft', + 'unique', + 'Optional Rules', + 'int', + 'creator', + 'Primal', + 'simple', + 'golem', + 'Void', + 'Armour', + 'spellsword', + 'General', + 'Asian', + 'Bringers of chaos', + 'Optional Feature', + 'subraces', + 'Galanoth', + 'barbarian subclass', + 'felhearth', + 'modular', + 'Vampires', + 'wysteria', + 'adaptation', + 'beasts', + 'naruto', + 'ninja', + 'Psionic', + 'Guns', + 'Crystal', + 'Guardian', + 'NonProfit', + 'Mimic', + 'languages', + 'Epic Boons', + 'Primer', + 'Icewind Dale', + 'joke', + 'lycan', + 'CR3', + 'Armors', + 'ff7', + 'materia', + 'final fantasy 7 remake', + 'esper', + 'ff7 remake', + 'gargantuan', + 'Frog', + 'CR5', + 'blank', + 'monster hunter', + 'league of legends', + 'french', + 'Pokémon', + 'kobold', + 'soul', + 'ffxi', + 'd10', + 'Roman', + 'Cute', + 'DD5', + 'variant', + 'tree', + 'fr', + 'Scenario', + 'lycanthrope', + 'druide', + 'staff', + 'eios', + 'arkheneios', + 'Runic', + 'Work', + 'Ukrainian', + 'cover-page', + 'mage', + 'deities', + 'gods', + 'Boss Fight', + 'Lair', + 'WBTW', + 'roguish archetype', + 'Character Option', + 'Shortsword', + 'Illrigger', + 'Bloodborne', + 'cr6', + 'Priest', + 'Hamon', + 'Toonkind', + 'rol', + 'Strength', + 'forgotten realms', + 'Spanish', + 'Conclave', + 'Electro', + 'Magical Tattoos', + 'Matt Mercer', + 'Wildemount', + 'Mighty Nien', + 'Campaign 2', + 'Resistances', + 'Bug', + 'impression', + 'PF', + 'Magnus Archives', + 'ice', + 'speed', + 'Generic NPC', + 'Titanic', + 'Ink Friendly', + 'bleed', + 'elder scrolls', + 'Immortal', + 'LMOP', + 'Travel', + 'Olphus', + '3d6', + 'heist', + 'World History', + 'ghost', + 'genie', + 'kids on bikes', + 'Russia', + 'conclave', + 'overhaul', + 'manual', + 'Adventures In Eden', + 'Downtime', + 'hamon', + 'cloak', + 'shadowfell', + 'Hellfire', + 'Paladin Oath', + 'Genshin', + 'Nation', + 'air', + 'Magical Item', + 'War', + 'Original', + 'Monstrous Compendium', + 'Calamity', + 'Warden', + 'Apocalypse', + 'shield', + 'AC', + 'expansion', + 'Concentration', + 'charm', + 'Weave', + 'lycanthropy', + 'raza', + 'far realm', + 'fighter subclass', + 'ita', + 'Pirate', + 'Laranja', + 'Grapple', + 'EastByForce', + 'hobgoblin', + 'oneshot-notes', + 'Holy', + 'optional', + 'type:cenario', + 'group:core', + 'The Brewery', + 'Alcance', + 'Morrowind', + 'Indigo', + 'Divino', + '2nd Level', + 'Sub-Class', + 'cantrips', + 'Cloak', + 'battle master', + 'Dark', + 'Puzzle', + 'Lucky', + 'consumable', + 'rebalance', + 'Shove', + 'Area Control', + 'Vanguard', + 'funny', + 'e5', + 'Dragonlance', + 'psion', + 'initiative', + 'Tactician', + 'Inspiration', + 'artificier', + 'way', + 'inspired', + 'historia', + 'Medusa', + '2 part', + 'holy', + 'gift', + 'Nimble', + 'mostri', + 'phoenix', + 'travel', + 'Class Template', + 'Intimidation', + 'constructs', + 'P666', + 'Formatting', + 'Divinity', + 'Rod', + 'Language', + 'yokai', + 'rune', + 'western', + 'vampires', + 'flying', + 'cute', + 'Enemy', + 'boon', + 'Tables', + 'ShadowFight', + 'meta: Theme', + 'SCS', + 'vanthampur villa', + 'CoA', + 'shop', + 'destiny', + 'magical weapon', + 'Arcane Arcade', + 'XP to Level 3', + 'Dice Average RPG', + 'Pip-Boy', + 'Dragon Heist', + 'session notes', + 'tattoo', + 'flick', + 'P6:66', + 'Comic Character', + 'experiment', + 'Minerva', + 'type:Spellbook', + 'Realmfall', + 'Wand', + 'halfling', + 'sw5e', + 'implementar AP', + 'Mask', + 'Gazook89', + 'Weltenrauch-Chroniken', + 'MiA', + 'Made in Abyss', + 'français', + 'fae', + 'Lemuria', + 'Mork Borg', + 'guerrier', + 'prunus', + 'condition', + 'pf2', + 'tr', + 'costrutto', + 'German', + 'project moon', + '5r', + 'galles', + 'Project moon', + 'Yisang', + 'Spicebush', + 'player-accessible', + 'Especie', + 'Westmarch', + 'a', + 'Cart', + 'Magus', + 'group:Mchael Galvis', + 'tip', + 'werewolf', + 'mundane', + 'garrett', + 'unarmed', + 'Arcane Odyssey', + 'Tomb of Divinity', + 'pets', + 'Video Game', + '4 part', + 'pbta', + 'Druids', + 'multiclass', + 'manuale', + 'mimic', + 'plane shift', + 'Dotes', + 'Hechizos', + 'Infernal', + 'Enhanced', + 'done', + 'Mission report', + 'Blanks', + 'Masks', + 'Ultimate Ability', + 'shadow-slave', + 'Advertising', + 'transform', + 'Fullmetal Alchemist', + 'Fullmetal Alchemist Brotherhood', + 'tag:TAoF&F', + 'Dwarves', + 'Humans', + 'Nine Hells', + 'Devils', + 'Archons', + 'CR 15', + 'Troglodytes', + 'Goliath', + 'retired', + 'boots', + 'ranged', + 'shields', + 'Zhentarim', + 'World of Warcraft', + 'Frontline', + 'Guildmaster\'s Guide to Ravnica', + 'Dungeons & Dragons 5e', + 'beholder', + 'NEEDS FIXING', + 'mechanic', + 'Loot', + 'champion', + 'Runes', + 'Shield', + 'Punch', + 'Sniper', + 'Magical Girl', + 'NotDND', + 'story', + 'Sleep', + 'Bard College', + 'Illusion', + 'Thunder', + 'Defender', + 'Genasi', + 'troll', + 'Gehenna', + 'Yugoloth', + 'social', + 'Player Class', + 'homebrew class', + 'CR 16', + 'Ghost', + 'Kobolds', + 'Trolls', + 'Yuan-Ti', + 'Elder Scrolls Offline', + 'armure', + 'Mage', + 'CR 18', + 'Technology', + 'Mystery', + 'darkness', + 'Airship', + 'New Campaign', + 'Warframe', + 'Wizard Subclass', + 'Gold', + 'Candor', + 'Overhaul', + 'Dragon Knight', + 'Enoreth', + 'Artifacts', + 'New', + 'AMMO', + 'Campagne', + 'Valbise', + 'Subclasseptember', + 'Mecha', + 'Yu-Gi-Oh', + 'Goblinoid', + 'underwater', + 'SW5E', + 'bardo' +]; \ No newline at end of file diff --git a/client/homebrew/homebrew.jsx b/client/homebrew/homebrew.jsx index 8470b3889..99b3e8fb4 100644 --- a/client/homebrew/homebrew.jsx +++ b/client/homebrew/homebrew.jsx @@ -1,8 +1,7 @@ - -import 'core-js/es/string/to-well-formed.js'; //Polyfill for older browsers +import 'core-js/es/string/to-well-formed.js'; // Polyfill for older browsers import './homebrew.less'; import React from 'react'; -import { StaticRouter as Router, Route, Routes, useParams, useSearchParams } from 'react-router'; +import { BrowserRouter as Router, Routes, Route, useParams, useSearchParams } from 'react-router'; import { updateLocalStorage } from './utils/updateLocalStorage/updateLocalStorageKeys.js'; @@ -41,24 +40,34 @@ const Homebrew = (props)=>{ brews } = props; - global.account = account; - global.version = version; - global.config = config; - const backgroundObject = ()=>{ - if(global.config.deployment || (config.local && config.development)){ - const bgText = global.config.deployment || 'Local'; - return { - backgroundImage : `url("data:image/svg+xml;utf8,${bgText}")` - }; + if(config?.deployment || (config?.local && config?.development)) { + const bgText = config?.deployment || 'Local'; + return { + backgroundImage : `url("data:image/svg+xml;utf8,${bgText}")` + }; } return null; }; + updateLocalStorage(); + if(brew.pureError) { + return ( + +
+ + } /> + +
+
+ ); + } + + return ( - -
+ +
} /> } /> @@ -81,4 +90,4 @@ const Homebrew = (props)=>{ ); }; -module.exports = Homebrew; \ No newline at end of file +export default Homebrew; diff --git a/client/homebrew/homebrew.less b/client/homebrew/homebrew.less index 2cbc35857..9bafadffe 100644 --- a/client/homebrew/homebrew.less +++ b/client/homebrew/homebrew.less @@ -1,4 +1,4 @@ -@import 'naturalcrit/styles/core.less'; +@import '@sharedStyles/core.less'; .homebrew { height : 100%; background-color:@steel; diff --git a/client/homebrew/main.jsx b/client/homebrew/main.jsx new file mode 100644 index 000000000..635729d49 --- /dev/null +++ b/client/homebrew/main.jsx @@ -0,0 +1,6 @@ +import { createRoot } from 'react-dom/client'; +import Homebrew from './homebrew.jsx'; + +const props = window.__INITIAL_PROPS__ || {}; + +createRoot(document.getElementById('reactRoot')).render(); diff --git a/client/homebrew/navbar/account.navitem.jsx b/client/homebrew/navbar/account.navitem.jsx index 8c0e92023..0be06c471 100644 --- a/client/homebrew/navbar/account.navitem.jsx +++ b/client/homebrew/navbar/account.navitem.jsx @@ -97,7 +97,7 @@ const Account = createReactClass({ // Logged out // LOCAL ONLY - if(global.config.local) { + if(global.config?.local) { return login ; diff --git a/client/homebrew/navbar/error-navitem.less b/client/homebrew/navbar/error-navitem.less index 637ddac95..4da665915 100644 --- a/client/homebrew/navbar/error-navitem.less +++ b/client/homebrew/navbar/error-navitem.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/core.less'; + .navItem.error { position : relative; background-color : @red; diff --git a/client/homebrew/navbar/metadata.navitem.jsx b/client/homebrew/navbar/metadata.navitem.jsx index bfea2e81a..8ee6b72c0 100644 --- a/client/homebrew/navbar/metadata.navitem.jsx +++ b/client/homebrew/navbar/metadata.navitem.jsx @@ -46,11 +46,6 @@ const MetadataNav = createReactClass({ ; }, - getSystems : function(){ - if(!this.props.brew.systems || this.props.brew.systems.length == 0) return 'No systems'; - return this.props.brew.systems.join(', '); - }, - renderMetaWindow : function(){ return
@@ -65,10 +60,6 @@ const MetadataNav = createReactClass({

Tags

{this.getTags()}

-
-

Systems

-

{this.getSystems()}

-

Updated

{Moment(this.props.brew.updatedAt).fromNow()}

diff --git a/client/homebrew/navbar/navbar.jsx b/client/homebrew/navbar/navbar.jsx index e75be8d59..db9a836c9 100644 --- a/client/homebrew/navbar/navbar.jsx +++ b/client/homebrew/navbar/navbar.jsx @@ -8,16 +8,10 @@ import PatreonNavItem from './patreon.navitem.jsx'; const Navbar = createReactClass({ displayName : 'Navbar', getInitialState : function() { - return { - //showNonChromeWarning : false, - ver : '0.0.0' - }; - }, - - getInitialState : function() { - return { - ver : global.version - }; + return { + // showNonChromeWarning: false, // uncomment if needed + ver : global.version || '0.0.0' + }; }, /* diff --git a/client/homebrew/navbar/navbar.less b/client/homebrew/navbar/navbar.less index 7b0217bf8..eb518e808 100644 --- a/client/homebrew/navbar/navbar.less +++ b/client/homebrew/navbar/navbar.less @@ -1,4 +1,4 @@ -@import 'naturalcrit/styles/colors.less'; +@import '@sharedStyles/core.less'; @navbarHeight : 28px; @viewerToolsHeight : 32px; diff --git a/client/homebrew/navbar/newbrew.navitem.jsx b/client/homebrew/navbar/newbrew.navitem.jsx index 4664d509b..5c91f8465 100644 --- a/client/homebrew/navbar/newbrew.navitem.jsx +++ b/client/homebrew/navbar/newbrew.navitem.jsx @@ -1,7 +1,7 @@ import React from 'react'; import _ from 'lodash'; import Nav from './nav.jsx'; -import { splitTextStyleAndMetadata } from '../../../shared/helpers.js'; +import { splitTextStyleAndMetadata } from '@shared/helpers.js'; const BREWKEY = 'HB_newPage_content'; const STYLEKEY = 'HB_newPage_style'; @@ -24,7 +24,7 @@ const NewBrew = ()=>{ localStorage.setItem(BREWKEY, newBrew.text); localStorage.setItem(STYLEKEY, newBrew.style); localStorage.setItem(METAKEY, JSON.stringify( - _.pick(newBrew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang']) + _.pick(newBrew, ['title', 'description', 'tags', 'renderer', 'theme', 'lang']) )); window.location.href = '/new'; return; diff --git a/client/homebrew/navbar/print.navitem.jsx b/client/homebrew/navbar/print.navitem.jsx index 271e17027..a60522986 100644 --- a/client/homebrew/navbar/print.navitem.jsx +++ b/client/homebrew/navbar/print.navitem.jsx @@ -1,6 +1,6 @@ import React from 'react'; import Nav from './nav.jsx'; -import { printCurrentBrew, scrapeBrewHTML, scrapeBrewZip } from '../../../shared/helpers.js'; +import { printCurrentBrew, scrapeBrewHTML, scrapeBrewZip } from '@shared/helpers.js'; export default function(props){ return diff --git a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less index d335f3ca9..93685947c 100644 --- a/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less +++ b/client/homebrew/pages/basePages/listPage/brewItem/brewItem.less @@ -1,3 +1,4 @@ +@import '@sharedStyles/core.less'; .brewItem { position : relative; diff --git a/client/homebrew/pages/editPage/editPage.jsx b/client/homebrew/pages/editPage/editPage.jsx index 29cd7c35a..55079acb5 100644 --- a/client/homebrew/pages/editPage/editPage.jsx +++ b/client/homebrew/pages/editPage/editPage.jsx @@ -4,34 +4,35 @@ import './editPage.less'; // Common imports import React, { useState, useEffect, useRef } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import _ from 'lodash'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import NewBrewItem from '../../navbar/newbrew.navitem.jsx'; -import AccountNavItem from '../../navbar/account.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import VaultNavItem from '../../navbar/vault.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports -import { Meta } from 'vitreum/headtags'; +import Headtags from '../../../../vitreum/headtags.js'; +const Meta = Headtags.Meta; import { md5 } from 'hash-wasm'; import { gzipSync, strToU8 } from 'fflate'; import { makePatches, stringifyPatches } from '@sanity/diff-match-patch'; -import ShareNavItem from '../../navbar/share.navitem.jsx'; +import ShareNavItem from '@navbar/share.navitem.jsx'; import LockNotification from './lockNotification/lockNotification.jsx'; import { updateHistory, versionHistoryGarbageCollection } from '../../utils/versionHistory.js'; import googleDriveIcon from '../../googleDrive.svg'; @@ -56,28 +57,28 @@ const EditPage = (props)=>{ ...props }; - const [currentBrew , setCurrentBrew ] = useState(props.brew); - const [isSaving , setIsSaving ] = useState(false); - const [lastSavedTime , setLastSavedTime ] = useState(new Date()); - const [saveGoogle , setSaveGoogle ] = useState(!!props.brew.googleId); - const [error , setError ] = useState(null); - const [HTMLErrors , setHTMLErrors ] = useState(Markdown.validate(props.brew.text)); - const [currentEditorViewPageNum , setCurrentEditorViewPageNum ] = useState(1); + const [currentBrew, setCurrentBrew] = useState(props.brew); + const [isSaving, setIsSaving] = useState(false); + const [lastSavedTime, setLastSavedTime] = useState(new Date()); + const [saveGoogle, setSaveGoogle] = useState(!!props.brew.googleId); + const [error, setError] = useState(null); + const [HTMLErrors, setHTMLErrors] = useState(Markdown.validate(props.brew.text)); + const [currentEditorViewPageNum, setCurrentEditorViewPageNum] = useState(1); const [currentEditorCursorPageNum, setCurrentEditorCursorPageNum] = useState(1); const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1); - const [themeBundle , setThemeBundle ] = useState({}); - const [unsavedChanges , setUnsavedChanges ] = useState(false); - const [alertTrashedGoogleBrew , setAlertTrashedGoogleBrew ] = useState(props.brew.trashed); - const [alertLoginToTransfer , setAlertLoginToTransfer ] = useState(false); - const [confirmGoogleTransfer , setConfirmGoogleTransfer ] = useState(false); - const [autoSaveEnabled , setAutoSaveEnabled ] = useState(true); - const [warnUnsavedChanges , setWarnUnsavedChanges ] = useState(true); + const [themeBundle, setThemeBundle] = useState({}); + const [unsavedChanges, setUnsavedChanges] = useState(false); + const [alertTrashedGoogleBrew, setAlertTrashedGoogleBrew] = useState(props.brew.trashed); + const [alertLoginToTransfer, setAlertLoginToTransfer] = useState(false); + const [confirmGoogleTransfer, setConfirmGoogleTransfer] = useState(false); + const [autoSaveEnabled, setAutoSaveEnabled] = useState(true); + const [warnUnsavedChanges, setWarnUnsavedChanges] = useState(true); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); const saveTimeout = useRef(null); const warnUnsavedTimeout = useRef(null); - const trySaveRef = useRef(trySave); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew + const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges useEffect(()=>{ diff --git a/client/homebrew/pages/errorPage/errorPage.jsx b/client/homebrew/pages/errorPage/errorPage.jsx index ffbfc43bb..837775b97 100644 --- a/client/homebrew/pages/errorPage/errorPage.jsx +++ b/client/homebrew/pages/errorPage/errorPage.jsx @@ -1,7 +1,7 @@ import './errorPage.less'; import React from 'react'; import UIPage from '../basePages/uiPage/uiPage.jsx'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import ErrorIndex from './errors/errorIndex.js'; const ErrorPage = ({ brew })=>{ diff --git a/client/homebrew/pages/errorPage/errorPage.less b/client/homebrew/pages/errorPage/errorPage.less index 2d10301e0..df8dcf98d 100644 --- a/client/homebrew/pages/errorPage/errorPage.less +++ b/client/homebrew/pages/errorPage/errorPage.less @@ -1,7 +1,6 @@ .homebrew { - .uiPage.sitePage { + .uiPage.sitePage:has(.errorTitle) { .errorTitle { - //background-color: @orange; color : #D02727; text-align : center; } diff --git a/client/homebrew/pages/homePage/homePage.jsx b/client/homebrew/pages/homePage/homePage.jsx index eede24428..019d1778b 100644 --- a/client/homebrew/pages/homePage/homePage.jsx +++ b/client/homebrew/pages/homePage/homePage.jsx @@ -1,33 +1,34 @@ -/* eslint-disable max-lines */ + import './homePage.less'; // Common imports import React, { useState, useEffect, useRef } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import NewBrewItem from '../../navbar/newbrew.navitem.jsx'; -import AccountNavItem from '../../navbar/account.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import VaultNavItem from '../../navbar/vault.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports -import { Meta } from 'vitreum/headtags'; +import Headtags from '@vitreum/headtags.js'; +const Meta = Headtags.Meta; const BREWKEY = 'homebrewery-new'; const STYLEKEY = 'homebrewery-new-style'; @@ -44,16 +45,16 @@ const HomePage =(props)=>{ ...props }; - const [currentBrew , setCurrentBrew] = useState(props.brew); - const [error , setError] = useState(undefined); - const [HTMLErrors , setHTMLErrors] = useState(Markdown.validate(props.brew.text)); - const [currentEditorViewPageNum , setCurrentEditorViewPageNum] = useState(1); + const [currentBrew, setCurrentBrew] = useState(props.brew); + const [error, setError] = useState(undefined); + const [HTMLErrors, setHTMLErrors] = useState(Markdown.validate(props.brew.text)); + const [currentEditorViewPageNum, setCurrentEditorViewPageNum] = useState(1); const [currentEditorCursorPageNum, setCurrentEditorCursorPageNum] = useState(1); const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1); - const [themeBundle , setThemeBundle] = useState({}); - const [unsavedChanges , setUnsavedChanges] = useState(false); - const [isSaving , setIsSaving] = useState(false); - const [autoSaveEnabled , setAutoSaveEnable] = useState(false); + const [themeBundle, setThemeBundle] = useState({}); + const [unsavedChanges, setUnsavedChanges] = useState(false); + const [isSaving, setIsSaving] = useState(false); + const [autoSaveEnabled, setAutoSaveEnable] = useState(false); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); diff --git a/client/homebrew/pages/homePage/homePage.less b/client/homebrew/pages/homePage/homePage.less index b89c2c7dd..fd072c1e1 100644 --- a/client/homebrew/pages/homePage/homePage.less +++ b/client/homebrew/pages/homePage/homePage.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/core.less'; + .homePage { position : relative; a.floatingNewButton { diff --git a/client/homebrew/pages/newPage/newPage.jsx b/client/homebrew/pages/newPage/newPage.jsx index 1559d223c..7ddb05c0b 100644 --- a/client/homebrew/pages/newPage/newPage.jsx +++ b/client/homebrew/pages/newPage/newPage.jsx @@ -4,29 +4,28 @@ import './newPage.less'; // Common imports import React, { useState, useEffect, useRef } from 'react'; import request from '../../utils/request-middleware.js'; -import Markdown from '../../../../shared/markdown.js'; +import Markdown from '@shared/markdown.js'; import _ from 'lodash'; import { DEFAULT_BREW } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle, splitTextStyleAndMetadata } from '@shared/helpers.js'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import Editor from '../../editor/editor.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import NewBrewItem from '../../navbar/newbrew.navitem.jsx'; -import AccountNavItem from '../../navbar/account.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import VaultNavItem from '../../navbar/vault.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import NewBrewItem from '@navbar/newbrew.navitem.jsx'; +import AccountNavItem from '@navbar/account.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import VaultNavItem from '@navbar/vault.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; // Page specific imports -import { Meta } from 'vitreum/headtags'; const BREWKEY = 'HB_newPage_content'; const STYLEKEY = 'HB_newPage_style'; @@ -43,23 +42,23 @@ const NewPage = (props)=>{ ...props }; - const [currentBrew , setCurrentBrew ] = useState(props.brew); - const [isSaving , setIsSaving ] = useState(false); - const [saveGoogle , setSaveGoogle ] = useState(global.account?.googleId ? true : false); - const [error , setError ] = useState(null); - const [HTMLErrors , setHTMLErrors ] = useState(Markdown.validate(props.brew.text)); - const [currentEditorViewPageNum , setCurrentEditorViewPageNum ] = useState(1); + const [currentBrew, setCurrentBrew] = useState(props.brew); + const [isSaving, setIsSaving] = useState(false); + const [saveGoogle, setSaveGoogle] = useState(global.account?.googleId ? true : false); + const [error, setError] = useState(null); + const [HTMLErrors, setHTMLErrors] = useState(Markdown.validate(props.brew.text)); + const [currentEditorViewPageNum, setCurrentEditorViewPageNum] = useState(1); const [currentEditorCursorPageNum, setCurrentEditorCursorPageNum] = useState(1); const [currentBrewRendererPageNum, setCurrentBrewRendererPageNum] = useState(1); - const [themeBundle , setThemeBundle ] = useState({}); - const [unsavedChanges , setUnsavedChanges ] = useState(false); - const [autoSaveEnabled , setAutoSaveEnabled ] = useState(false); + const [themeBundle, setThemeBundle] = useState({}); + const [unsavedChanges, setUnsavedChanges] = useState(false); + const [autoSaveEnabled, setAutoSaveEnabled] = useState(false); const editorRef = useRef(null); const lastSavedBrew = useRef(_.cloneDeep(props.brew)); // const saveTimeout = useRef(null); // const warnUnsavedTimeout = useRef(null); - const trySaveRef = useRef(trySave); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew + const trySaveRef = useRef(null); // CTRL+S listener lives outside React and needs ref to use trySave with latest copy of brew const unsavedChangesRef = useRef(unsavedChanges); // Similarly, onBeforeUnload lives outside React and needs ref to unsavedChanges useEffect(()=>{ diff --git a/client/homebrew/pages/newPage/newPage.less b/client/homebrew/pages/newPage/newPage.less index d2f07ac40..39befb44e 100644 --- a/client/homebrew/pages/newPage/newPage.less +++ b/client/homebrew/pages/newPage/newPage.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/colors.less'; + .newPage { .navItem.save { background-color : @orange; diff --git a/client/homebrew/pages/sharePage/sharePage.jsx b/client/homebrew/pages/sharePage/sharePage.jsx index 25b9302ef..c0838f42b 100644 --- a/client/homebrew/pages/sharePage/sharePage.jsx +++ b/client/homebrew/pages/sharePage/sharePage.jsx @@ -1,18 +1,19 @@ import './sharePage.less'; import React, { useState, useEffect, useCallback } from 'react'; -import { Meta } from 'vitreum/headtags'; +import Headtags from '../../../../vitreum/headtags.js'; +const Meta = Headtags.Meta; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import MetadataNav from '../../navbar/metadata.navitem.jsx'; -import PrintNavItem from '../../navbar/print.navitem.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import MetadataNav from '@navbar/metadata.navitem.jsx'; +import PrintNavItem from '@navbar/print.navitem.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; -import Account from '../../navbar/account.navitem.jsx'; +import Account from '@navbar/account.navitem.jsx'; import BrewRenderer from '../../brewRenderer/brewRenderer.jsx'; import { DEFAULT_BREW_LOAD } from '../../../../server/brewDefaults.js'; -import { printCurrentBrew, fetchThemeBundle } from '../../../../shared/helpers.js'; +import { printCurrentBrew, fetchThemeBundle } from '@shared/helpers.js'; const SharePage = (props)=>{ const { brew = DEFAULT_BREW_LOAD, disableMeta = false, share = true } = props; diff --git a/client/homebrew/pages/userPage/userPage.jsx b/client/homebrew/pages/userPage/userPage.jsx index a6a43858e..0b2ebb56b 100644 --- a/client/homebrew/pages/userPage/userPage.jsx +++ b/client/homebrew/pages/userPage/userPage.jsx @@ -3,15 +3,15 @@ import _ from 'lodash'; import ListPage from '../basePages/listPage/listPage.jsx'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; -import Account from '../../navbar/account.navitem.jsx'; -import NewBrew from '../../navbar/newbrew.navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; -import ErrorNavItem from '../../navbar/error-navitem.jsx'; -import VaultNavitem from '../../navbar/vault.navitem.jsx'; +import Account from '@navbar/account.navitem.jsx'; +import NewBrew from '@navbar/newbrew.navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; +import ErrorNavItem from '@navbar/error-navitem.jsx'; +import VaultNavitem from '@navbar/vault.navitem.jsx'; const UserPage = (props)=>{ props = { diff --git a/client/homebrew/pages/vaultPage/vaultPage.jsx b/client/homebrew/pages/vaultPage/vaultPage.jsx index 3a8c6bc25..e6a9768bb 100644 --- a/client/homebrew/pages/vaultPage/vaultPage.jsx +++ b/client/homebrew/pages/vaultPage/vaultPage.jsx @@ -3,13 +3,13 @@ import './vaultPage.less'; import React, { useState, useEffect, useRef } from 'react'; -import Nav from '../../navbar/nav.jsx'; -import Navbar from '../../navbar/navbar.jsx'; -import RecentNavItems from '../../navbar/recent.navitem.jsx'; +import Nav from '@navbar/nav.jsx'; +import Navbar from '@navbar/navbar.jsx'; +import RecentNavItems from '@navbar/recent.navitem.jsx'; const { both: RecentNavItem } = RecentNavItems; -import Account from '../../navbar/account.navitem.jsx'; -import NewBrew from '../../navbar/newbrew.navitem.jsx'; -import HelpNavItem from '../../navbar/help.navitem.jsx'; +import Account from '@navbar/account.navitem.jsx'; +import NewBrew from '@navbar/newbrew.navitem.jsx'; +import HelpNavItem from '@navbar/help.navitem.jsx'; import BrewItem from '../basePages/listPage/brewItem/brewItem.jsx'; import SplitPane from '../../../components/splitPane/splitPane.jsx'; import ErrorIndex from '../errorPage/errors/errorIndex.js'; diff --git a/client/homebrew/pages/vaultPage/vaultPage.less b/client/homebrew/pages/vaultPage/vaultPage.less index 304fefc72..b2010b59b 100644 --- a/client/homebrew/pages/vaultPage/vaultPage.less +++ b/client/homebrew/pages/vaultPage/vaultPage.less @@ -1,3 +1,5 @@ +@import '@sharedStyles/core.less'; + .vaultPage { height : 100%; overflow-y : hidden; diff --git a/client/template.js b/client/template.js deleted file mode 100644 index 537be6748..000000000 --- a/client/template.js +++ /dev/null @@ -1,33 +0,0 @@ -const template = async function(name, title='', props = {}){ - const ogTags = []; - const ogMeta = props.ogMeta ?? {}; - Object.entries(ogMeta).forEach(([key, value])=>{ - if(!value) return; - const tag = ``; - ogTags.push(tag); - }); - const ogMetaTags = ogTags.join('\n'); - - const ssrModule = await import(`../build/${name}/ssr.cjs`); - - return ` - - - - - - - ${ogMetaTags} - - ${title.length ? `${title} - The Homebrewery`: 'The Homebrewery - NaturalCrit'} - - -
${ssrModule.default(props)}
- - - - - `; -}; - -export default template; \ No newline at end of file diff --git a/themes/codeMirror/editorThemes.json b/editorThemes.json similarity index 100% rename from themes/codeMirror/editorThemes.json rename to editorThemes.json diff --git a/index.html b/index.html new file mode 100644 index 000000000..5ee864b28 --- /dev/null +++ b/index.html @@ -0,0 +1,29 @@ + + + + + + + + + + The Homebrewery - NaturalCrit + + + +
+ + + + diff --git a/package-lock.json b/package-lock.json index 2b3892c88..6e710b835 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,10 +14,11 @@ "@babel/plugin-transform-runtime": "^7.29.0", "@babel/preset-env": "^7.29.0", "@babel/preset-react": "^7.28.5", - "@babel/runtime": "^7.28.4", + "@babel/runtime": "^7.28.6", "@dmsnell/diff-match-patch": "^1.1.0", "@googleapis/drive": "^20.1.0", "@sanity/diff-match-patch": "^3.2.0", + "@vitejs/plugin-react": "^5.1.2", "body-parser": "^2.2.0", "classnames": "^2.5.1", "codemirror": "^5.65.6", @@ -26,7 +27,6 @@ "cors": "^2.8.5", "create-react-class": "^15.7.0", "dedent": "^1.7.1", - "expr-eval": "^2.0.2", "express": "^5.1.0", "express-async-handler": "^1.2.0", "express-static-gzip": "3.0.0", @@ -36,7 +36,7 @@ "idb-keyval": "^6.2.2", "js-yaml": "^4.1.1", "jwt-simple": "^0.5.6", - "less": "^3.13.1", + "less": "^4.5.1", "lodash": "^4.17.21", "marked": "15.0.12", "marked-alignment-paragraphs": "^1.0.0", @@ -53,21 +53,19 @@ "mongoose": "^9.2.1", "nanoid": "5.1.6", "nconf": "^0.13.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-frame-component": "^4.1.3", - "react-router": "^7.9.6", - "romans": "^3.1.0", + "node": "^25.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-frame-component": "^5.2.7", + "react-router": "^7.13.1", "sanitize-filename": "1.6.3", - "superagent": "^10.2.1", - "vitreum": "git+https://git@github.com/calculuschild/vitreum.git", - "written-number": "^0.11.1" + "superagent": "^10.2.1" }, "devDependencies": { - "@stylistic/stylelint-plugin": "^4.0.0", + "@stylistic/stylelint-plugin": "^5.0.1", "babel-jest": "^30.2.0", "babel-plugin-transform-import-meta": "^2.3.3", - "eslint": "^9.39.1", + "eslint": "9.7", "eslint-plugin-jest": "^29.1.0", "eslint-plugin-react": "^7.37.5", "globals": "^16.4.0", @@ -76,14 +74,15 @@ "jsdom": "^28.1.0", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.25.0", - "stylelint-config-recess-order": "^7.3.0", - "stylelint-config-recommended": "^17.0.0", - "supertest": "^7.1.4" + "stylelint": "^17.4.0", + "stylelint-config-recess-order": "^7.6.1", + "stylelint-config-recommended": "^18.0.0", + "supertest": "^7.1.4", + "vite": "^7.3.1" }, "engines": { - "node": "^20.18.x", - "npm": "^10.8.x" + "node": ">=20.18 <25", + "npm": ">=10.8 <12" } }, "node_modules/@acemir/cssom": { @@ -94,114 +93,20 @@ "license": "MIT" }, "node_modules/@asamuzakjp/css-color": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.2.tgz", - "integrity": "sha512-NfBUvBaYgKIuq6E/RBLY1m0IohzNHAYyaJGuTK79Z23uNwmz2jl1mPsC5ZxCCxylinKhT1Amn5oNTlx1wN8cQg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz", + "integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^3.0.0", - "@csstools/css-color-parser": "^4.0.1", + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", "@csstools/css-parser-algorithms": "^4.0.0", "@csstools/css-tokenizer": "^4.0.0", - "lru-cache": "^11.2.5" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-calc": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", - "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "engines": { - "node": ">=20.19.0" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-color-parser": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.1.tgz", - "integrity": "sha512-vYwO15eRBEkeF6xjAno/KQ61HacNhfQuuU/eGwH67DplL0zD5ZixUa563phQvUelA07yDczIXdtmYojCphKJcw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "dependencies": { - "@csstools/color-helpers": "^6.0.1", - "@csstools/css-calc": "^3.0.0" + "lru-cache": "^11.2.6" }, "engines": { - "node": ">=20.19.0" - }, - "peerDependencies": { - "@csstools/css-parser-algorithms": "^4.0.0", - "@csstools/css-tokenizer": "^4.0.0" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-parser-algorithms": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", - "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "peer": true, - "engines": { - "node": ">=20.19.0" - }, - "peerDependencies": { - "@csstools/css-tokenizer": "^4.0.0" - } - }, - "node_modules/@asamuzakjp/css-color/node_modules/@csstools/css-tokenizer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", - "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/csstools" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - } - ], - "license": "MIT", - "peer": true, - "engines": { - "node": ">=20.19.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { @@ -273,7 +178,6 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -1614,6 +1518,36 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-transform-react-pure-annotations": { "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz", @@ -1951,7 +1885,6 @@ "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.28.5.tgz", "integrity": "sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==", "license": "MIT", - "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.27.1", "@babel/helper-validator-option": "^7.27.1", @@ -2042,16 +1975,16 @@ } }, "node_modules/@cacheable/memory": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.7.tgz", - "integrity": "sha512-RbxnxAMf89Tp1dLhXMS7ceft/PGsDl1Ip7T20z5nZ+pwIAsQ1p2izPjVG69oCLv/jfQ7HDPHTWK0c9rcAWXN3A==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.8.tgz", + "integrity": "sha512-FvEb29x5wVwu/Kf93IWwsOOEuhHh6dYCJF3vcKLzXc0KXIW181AOzv6ceT4ZpBHDvAfG60eqb+ekmrnLHIy+jw==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/utils": "^2.3.3", - "@keyv/bigmap": "^1.3.0", - "hookified": "^1.14.0", - "keyv": "^5.5.5" + "@cacheable/utils": "^2.4.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" } }, "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { @@ -2077,19 +2010,18 @@ "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@keyv/serialize": "^1.1.1" } }, "node_modules/@cacheable/utils": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.4.tgz", - "integrity": "sha512-knwKUJEYgIfwShABS1BX6JyJJTglAFcEU7EXqzTdiGCXur4voqkiJkdgZIQtWNFhynzDWERcTYv/sETMu3uJWA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.4.0.tgz", + "integrity": "sha512-PeMMsqjVq+bF0WBsxFBxr/WozBJiZKY0rUojuaCoIaKnEl3Ju1wfEwS+SV1DU/cSe8fqHIPiYJFif8T3MVt4cQ==", "dev": true, "license": "MIT", "dependencies": { - "hashery": "^1.3.0", + "hashery": "^1.5.0", "keyv": "^5.6.0" } }, @@ -2104,9 +2036,9 @@ } }, "node_modules/@csstools/color-helpers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.1.tgz", - "integrity": "sha512-NmXRccUJMk2AWA5A7e5a//3bCIMyOu2hAtdRYrhPPHjDxINuCwX1w6rnIZ4xjLcp0ayv6h8Pc3X0eJUGiAAXHQ==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", "dev": true, "funding": [ { @@ -2123,10 +2055,10 @@ "node": ">=20.19.0" } }, - "node_modules/@csstools/css-parser-algorithms": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", - "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "node_modules/@csstools/css-calc": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", + "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", "dev": true, "funding": [ { @@ -2139,18 +2071,69 @@ } ], "license": "MIT", - "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", + "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.1.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" } }, "node_modules/@csstools/css-syntax-patches-for-csstree": { - "version": "1.0.27", - "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.27.tgz", - "integrity": "sha512-sxP33Jwg1bviSUXAV43cVYdmjt2TLnLXNqCWl9xmxHawWVjGz/kEbdkr7F9pxJNBN2Mh+dq0crgItbW6tQvyow==", + "version": "1.0.29", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.29.tgz", + "integrity": "sha512-jx9GjkkP5YHuTmko2eWAvpPnb0mB4mGRr2U7XwVNwevm8nlpobZEVk+GNmiYMk2VuA75v+plfXWyroWKmICZXg==", "dev": true, "funding": [ { @@ -2165,9 +2148,9 @@ "license": "MIT-0" }, "node_modules/@csstools/css-tokenizer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", - "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", "dev": true, "funding": [ { @@ -2180,15 +2163,14 @@ } ], "license": "MIT", - "peer": true, "engines": { - "node": ">=18" + "node": ">=20.19.0" } }, "node_modules/@csstools/media-query-list-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz", - "integrity": "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-5.0.0.tgz", + "integrity": "sha512-T9lXmZOfnam3eMERPsszjY5NK0jX8RmThmmm99FZ8b7z8yMaFZWKwLWGZuTwdO3ddRY5fy13GmmEYZXB4I98Eg==", "dev": true, "funding": [ { @@ -2202,17 +2184,17 @@ ], "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4" + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" } }, - "node_modules/@csstools/selector-specificity": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz", - "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==", + "node_modules/@csstools/selector-resolve-nested": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-4.0.0.tgz", + "integrity": "sha512-9vAPxmp+Dx3wQBIUwc1v7Mdisw1kbbaGqXUM8QLTgWg7SoPGYtXBsMXvsFs/0Bn5yoFhcktzxNZGNaUt0VjgjA==", "dev": true, "funding": [ { @@ -2226,10 +2208,33 @@ ], "license": "MIT-0", "engines": { - "node": ">=18" + "node": ">=20.19.0" }, "peerDependencies": { - "postcss-selector-parser": "^7.0.0" + "postcss-selector-parser": "^7.1.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-6.0.0.tgz", + "integrity": "sha512-4sSgl78OtOXEX/2d++8A83zHNTgwCJMaR24FvsYL7Uf/VS8HZk9PTwR51elTbGqMuwH3szLvvOXEaVnqn0Z3zA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "postcss-selector-parser": "^7.1.1" } }, "node_modules/@dmsnell/diff-match-patch": { @@ -2238,17 +2243,6 @@ "integrity": "sha512-yejLPmM5pjsGvxS9gXablUSbInW7H976c/FJ4iQxWIm7/38xBySRemTPDe34lhg1gVLbJntX0+sH0jYfU+PN9A==", "license": "Apache-2.0" }, - "node_modules/@dual-bundle/import-meta-resolve": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz", - "integrity": "sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/JounQin" - } - }, "node_modules/@emnapi/core": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", @@ -2283,6 +2277,422 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", @@ -2326,13 +2736,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.17.1.tgz", + "integrity": "sha512-BlYOpej8AQ8Ev9xVqroV7a02JK3SkBAaN9GfMMH9W6Ch8FlQlkjGw4Ir7+FgYwfirivAf4t+GtzuAxqfukmISA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.7", + "@eslint/object-schema": "^2.1.4", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -2340,47 +2750,21 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.4.tgz", + "integrity": "sha512-4h4MVF8pmBsncB60r0wSJiIeUKTSD4m7FmTFThG8RHlsg9ajqckLm9OraguFGZE4vVdpiI1Q4+hFnisopmG6gQ==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", + "minimatch": "^3.1.3", "strip-json-comments": "^3.1.1" }, "engines": { @@ -2404,16 +2788,13 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.7.0.tgz", + "integrity": "sha512-ChuWDQenef8OSFnvuxv0TCVxEwmu3+hPNKvM9B34qpM0rDRbjL8t5QkQeHHeAfsKQjuH9wS82WeCi1J/owatng==", "dev": true, "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { @@ -2426,24 +2807,10 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@exodus/bytes": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.14.1.tgz", - "integrity": "sha512-OhkBFWI6GcRMUroChZiopRiSp2iAMvEBK47NhJooDqz1RERO4QuZIZnjP63TXX8GAiLABkYmX+fuQsdJ1dd2QQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", "dev": true, "license": "MIT", "engines": { @@ -2470,30 +2837,6 @@ "node": ">=12.0.0" } }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -2509,9 +2852,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2539,6 +2882,33 @@ "node": ">=12" } }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -3011,7 +3381,6 @@ "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", - "peer": true, "engines": { "node": "^14.21.3 || >=16" }, @@ -3089,6 +3458,337 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.3.tgz", + "integrity": "sha512-eybk3TjzzzV97Dlj5c+XrBFW57eTNhzod66y9HrBlzJ6NsCrWCp/2kaPS3K9wJmurBC0Tdw4yPjXKZqlznim3Q==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@sanity/diff-match-patch": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@sanity/diff-match-patch/-/diff-match-patch-3.2.0.tgz", @@ -3105,6 +3805,19 @@ "dev": true, "license": "MIT" }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@sinonjs/commons": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", @@ -3126,25 +3839,25 @@ } }, "node_modules/@stylistic/stylelint-plugin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-4.0.1.tgz", - "integrity": "sha512-jKZSZr/S/NehfgayNJI3O/JEq+W5lSeHUJNvdOebRPNFP2ZylTbAx/p5qR8scQFpiVzy1VQM9R+G0kIB62r1Pw==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-5.0.1.tgz", + "integrity": "sha512-NaVwCNVZ2LyPA3TnUwvjO9c6P6VUjgRB8UP8SOW+cAOJBVqPPuOIDawsvvtql/LhkuR3JuTdGvr/RM3dUl8l2Q==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "@csstools/media-query-list-parser": "^5.0.0", "postcss": "^8.5.6", - "postcss-selector-parser": "^7.1.0", + "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0", "style-search": "^0.1.0" }, "engines": { - "node": "^18.12 || >=20.9" + "node": ">=20.19.0" }, "peerDependencies": { - "stylelint": "^16.22.0" + "stylelint": "^17.0.0" } }, "node_modules/@tybys/wasm-util": { @@ -3162,7 +3875,6 @@ "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", @@ -3176,7 +3888,6 @@ "version": "7.27.0", "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -3186,7 +3897,6 @@ "version": "7.4.4", "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", @@ -3197,7 +3907,6 @@ "version": "7.28.0", "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.28.2" @@ -3207,7 +3916,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-coverage": { @@ -3237,18 +3945,11 @@ "@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==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", - "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", - "dev": true, + "version": "25.3.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.3.tgz", + "integrity": "sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==", + "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~7.18.0" @@ -3294,14 +3995,14 @@ "license": "MIT" }, "node_modules/@typescript-eslint/project-service": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.0.tgz", - "integrity": "sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.56.1.tgz", + "integrity": "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.56.0", - "@typescript-eslint/types": "^8.56.0", + "@typescript-eslint/tsconfig-utils": "^8.56.1", + "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "engines": { @@ -3316,14 +4017,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.0.tgz", - "integrity": "sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.56.1.tgz", + "integrity": "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0" + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3334,9 +4035,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.0.tgz", - "integrity": "sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.56.1.tgz", + "integrity": "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ==", "dev": true, "license": "MIT", "engines": { @@ -3351,9 +4052,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.0.tgz", - "integrity": "sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.56.1.tgz", + "integrity": "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw==", "dev": true, "license": "MIT", "engines": { @@ -3365,18 +4066,18 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.0.tgz", - "integrity": "sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.56.1.tgz", + "integrity": "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.56.0", - "@typescript-eslint/tsconfig-utils": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/visitor-keys": "8.56.0", + "@typescript-eslint/project-service": "8.56.1", + "@typescript-eslint/tsconfig-utils": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", - "minimatch": "^9.0.5", + "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" @@ -3392,27 +4093,40 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.4.tgz", + "integrity": "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.4.tgz", + "integrity": "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.2" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -3432,16 +4146,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.0.tgz", - "integrity": "sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.56.1.tgz", + "integrity": "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.56.0", - "@typescript-eslint/types": "8.56.0", - "@typescript-eslint/typescript-estree": "8.56.0" + "@typescript-eslint/scope-manager": "8.56.1", + "@typescript-eslint/types": "8.56.1", + "@typescript-eslint/typescript-estree": "8.56.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3456,13 +4170,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.56.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.0.tgz", - "integrity": "sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==", + "version": "8.56.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.56.1.tgz", + "integrity": "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.56.0", + "@typescript-eslint/types": "8.56.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -3474,9 +4188,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.0.tgz", - "integrity": "sha512-A0XeIi7CXU7nPlfHS9loMYEKxUaONu/hTEzHTGba9Huu94Cq1hPivf+DE5erJozZOky0LfvXAyrV/tcswpLI0Q==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -3762,6 +4476,26 @@ "win32" ] }, + "node_modules/@vitejs/plugin-react": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-5.1.4.tgz", + "integrity": "sha512-VIcFLdRi/VYRU8OL/puL7QXMYafHmqOnwTZY50U1JPlCNj30PxCMx65c494b1K9be9hX83KVt0+gTEwTWLqToA==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.29.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-rc.3", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.18.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, "node_modules/accepts": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", @@ -3776,12 +4510,11 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", + "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3799,38 +4532,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-node": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", - "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", - "license": "Apache-2.0", - "dependencies": { - "acorn": "^7.0.0", - "acorn-walk": "^7.0.0", - "xtend": "^4.0.2" - } - }, - "node_modules/acorn-node/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -3841,9 +4542,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -3874,15 +4575,12 @@ } }, "node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "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": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": ">=8" } }, "node_modules/ansi-styles": { @@ -3904,6 +4602,7 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -3919,33 +4618,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "license": "Python-2.0" }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -3986,25 +4658,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.findlast": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", @@ -4109,42 +4762,6 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, - "node_modules/asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "license": "MIT" - }, - "node_modules/assert": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.1.tgz", - "integrity": "sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==", - "license": "MIT", - "dependencies": { - "object.assign": "^4.1.4", - "util": "^0.10.4" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -4161,18 +4778,6 @@ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, - "node_modules/async-each": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz", - "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT" - }, "node_modules/async-function": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", @@ -4189,31 +4794,11 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, - "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/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "license": "(MIT OR Apache-2.0)", - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, "node_modules/available-typed-arrays": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, "license": "MIT", "dependencies": { "possible-typed-array-names": "^1.0.0" @@ -4383,49 +4968,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "license": "MIT", - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -4447,12 +4989,15 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.19", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", - "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", + "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", "license": "Apache-2.0", "bin": { - "baseline-browser-mapping": "dist/cli.js" + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/bidi-js": { @@ -4474,34 +5019,6 @@ "node": "*" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bn.js": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz", - "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==", - "license": "MIT" - }, "node_modules/body-parser": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", @@ -4530,6 +5047,7 @@ "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -4540,6 +5058,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -4548,227 +5067,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "license": "MIT" - }, - "node_modules/browser-pack": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", - "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", - "license": "MIT", - "dependencies": { - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "JSONStream": "^1.0.3", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" - }, - "bin": { - "browser-pack": "bin/cmd.js" - } - }, - "node_modules/browser-pack/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/browser-resolve": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-2.0.0.tgz", - "integrity": "sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==", - "license": "MIT", - "dependencies": { - "resolve": "^1.17.0" - } - }, - "node_modules/browserify": { - "version": "16.5.2", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.5.2.tgz", - "integrity": "sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g==", - "license": "MIT", - "dependencies": { - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^2.0.0", - "browserify-zlib": "~0.2.0", - "buffer": "~5.2.1", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "JSONStream": "^1.0.3", - "labeled-stream-splicer": "^2.0.0", - "mkdirp-classic": "^0.5.2", - "module-deps": "^6.2.3", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^3.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", - "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "browserify": "bin/cmd.js" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "license": "MIT", - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "license": "MIT", - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", - "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", - "license": "MIT", - "dependencies": { - "bn.js": "^5.2.1", - "randombytes": "^2.1.0", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz", - "integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==", - "license": "ISC", - "dependencies": { - "bn.js": "^5.2.2", - "browserify-rsa": "^4.1.1", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.6.1", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.9", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "license": "MIT", - "dependencies": { - "pako": "~1.0.5" - } - }, - "node_modules/browserify/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/browserify/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/browserify/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "node_modules/browserslist": { "version": "4.28.1", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", @@ -4788,7 +5086,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -4822,16 +5119,6 @@ "node": ">=20.19.0" } }, - "node_modules/buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", - "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", - "license": "MIT", - "dependencies": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" - } - }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -4842,18 +5129,7 @@ "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/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "license": "MIT" - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true, "license": "MIT" }, "node_modules/bytes": { @@ -4865,37 +5141,17 @@ "node": ">= 0.8" } }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "license": "MIT", - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cacheable": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.2.tgz", - "integrity": "sha512-w+ZuRNmex9c1TR9RcsxbfTKCjSL0rh1WA5SABbrWprIHeNBdmyQLSYonlDy9gpD+63XT8DgZ/wNh1Smvc9WnJA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.3.tgz", + "integrity": "sha512-iffYMX4zxKp54evOH27fm92hs+DeC1DhXmNVN8Tr94M/iZIV42dqTHSR2Ik4TOSPyOAwKr7Yu3rN9ALoLkbWyQ==", "dev": true, "license": "MIT", "dependencies": { - "@cacheable/memory": "^2.0.7", - "@cacheable/utils": "^2.3.3", + "@cacheable/memory": "^2.0.8", + "@cacheable/utils": "^2.4.0", "hookified": "^1.15.0", - "keyv": "^5.5.5", + "keyv": "^5.6.0", "qified": "^0.6.0" } }, @@ -4909,16 +5165,11 @@ "@keyv/serialize": "^1.1.1" } }, - "node_modules/cached-path-relative": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.1.0.tgz", - "integrity": "sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==", - "license": "MIT" - }, "node_modules/call-bind": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.0", @@ -4983,9 +5234,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001770", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", - "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", + "version": "1.0.30001776", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001776.tgz", + "integrity": "sha512-sg01JDPzZ9jGshqKSckOQthXnYwOEP50jeVFhaSFbZcOy05TiuuaffDOfcwtCisJ9kNQuLBFibYywv2Bgm9osw==", "funding": [ { "type": "opencollective", @@ -5029,42 +5280,6 @@ "node": ">=10" } }, - "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", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/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" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/ci-info": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", @@ -5081,20 +5296,6 @@ "node": ">=8" } }, - "node_modules/cipher-base": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", - "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/cjs-module-lexer": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", @@ -5102,21 +5303,6 @@ "dev": true, "license": "MIT" }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -5138,16 +5324,6 @@ "node": ">=12" } }, - "node_modules/cliui/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -5170,19 +5346,6 @@ "node": ">=8" } }, - "node_modules/cliui/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/cliui/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -5225,19 +5388,6 @@ "dev": true, "license": "MIT" }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "license": "MIT", - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -5263,33 +5413,6 @@ "dev": true, "license": "MIT" }, - "node_modules/combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", - "license": "MIT", - "dependencies": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" - } - }, - "node_modules/combine-source-map/node_modules/convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", - "license": "MIT" - }, - "node_modules/combine-source-map/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5315,32 +5438,7 @@ "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==" - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true, "license": "MIT" }, "node_modules/content-disposition": { @@ -5417,15 +5515,6 @@ "url": "https://github.com/sponsors/mesqueeb" } }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/core-js": { "version": "3.48.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.48.0.tgz", @@ -5450,12 +5539,6 @@ "url": "https://opencollective.com/core-js" } }, - "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/cors": { "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", @@ -5474,9 +5557,9 @@ } }, "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz", + "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5500,49 +5583,6 @@ } } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "license": "MIT" - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "node_modules/create-react-class": { "version": "15.7.0", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.7.0.tgz", @@ -5567,32 +5607,6 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.1.tgz", - "integrity": "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==", - "license": "MIT", - "dependencies": { - "browserify-cipher": "^1.0.1", - "browserify-sign": "^4.2.3", - "create-ecdh": "^4.0.4", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "diffie-hellman": "^5.0.3", - "hash-base": "~3.0.4", - "inherits": "^2.0.4", - "pbkdf2": "^3.1.2", - "public-encrypt": "^4.0.3", - "randombytes": "^2.1.0", - "randomfill": "^1.0.4" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/css-functions-list": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.3.3.tgz", @@ -5631,16 +5645,16 @@ } }, "node_modules/cssstyle": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.0.1.tgz", - "integrity": "sha512-IoJs7La+oFp/AB033wBStxNOJt4+9hHMxsXUPANcoXL2b3W4DZKghlJ2cI/eyeRZIQ9ysvYEorVhjrcYctWbog==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.2.0.tgz", + "integrity": "sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^4.1.2", - "@csstools/css-syntax-patches-for-csstree": "^1.0.26", + "@asamuzakjp/css-color": "^5.0.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", "css-tree": "^3.1.0", - "lru-cache": "^11.2.5" + "lru-cache": "^11.2.6" }, "engines": { "node": ">=20" @@ -5656,12 +5670,6 @@ "node": "20 || >=22" } }, - "node_modules/dash-ast": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", - "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", - "license": "Apache-2.0" - }, "node_modules/data-uri-to-buffer": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", @@ -5763,19 +5771,10 @@ "dev": true, "license": "MIT" }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/dedent": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", - "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "license": "MIT", "peerDependencies": { "babel-plugin-macros": "^3.1.0" @@ -5807,6 +5806,7 @@ "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==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", @@ -5824,6 +5824,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.0.1", @@ -5837,27 +5838,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/defined": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.1.tgz", - "integrity": "sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -5876,41 +5856,6 @@ "node": ">= 0.8" } }, - "node_modules/deps-sort": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.1.tgz", - "integrity": "sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==", - "license": "MIT", - "dependencies": { - "JSONStream": "^1.0.3", - "shasum-object": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" - }, - "bin": { - "deps-sort": "bin/cmd.js" - } - }, - "node_modules/deps-sort/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/des.js": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz", - "integrity": "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -5921,23 +5866,6 @@ "node": ">=8" } }, - "node_modules/detective": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.1.tgz", - "integrity": "sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==", - "license": "MIT", - "dependencies": { - "acorn-node": "^1.8.2", - "defined": "^1.0.0", - "minimist": "^1.2.6" - }, - "bin": { - "detective": "bin/detective.js" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/dezalgo": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", @@ -5948,36 +5876,6 @@ "wrappy": "1" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "license": "MIT" - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", @@ -5991,16 +5889,6 @@ "node": ">=0.10.0" } }, - "node_modules/domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "license": "MIT", - "engines": { - "node": ">=0.4", - "npm": ">=1.2" - } - }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -6015,15 +5903,6 @@ "node": ">= 0.4" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "license": "BSD-3-Clause", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -6046,32 +5925,11 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", - "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", + "version": "1.5.307", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz", + "integrity": "sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg==", "license": "ISC" }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "license": "MIT" - }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", @@ -6319,6 +6177,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -6348,33 +6247,28 @@ } }, "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "version": "9.7.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.7.0.tgz", + "integrity": "sha512-FzJ9D/0nGiCGBf8UXO/IGLTgLVzIxze1zpfA8Ton2mjLovXdAPlYDv+MQDcqj3TmrhAGYfOpz9RfR+ent0AgAw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.17.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.7.0", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", + "@humanwhocodes/retry": "^0.3.0", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", + "cross-spawn": "^7.0.2", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -6384,11 +6278,15 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3" + "optionator": "^0.9.3", + "strip-ansi": "^6.0.1", + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -6398,14 +6296,6 @@ }, "funding": { "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } } }, "node_modules/eslint-plugin-jest": { @@ -6660,25 +6550,6 @@ "node": ">= 0.6" } }, - "node_modules/events": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", - "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", - "license": "MIT", - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "license": "MIT", - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -6720,39 +6591,6 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "license": "MIT", - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/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/expand-brackets/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/expect": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", @@ -6852,62 +6690,6 @@ "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" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "license": "MIT", - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7054,17 +6836,11 @@ "node": ">=16.0.0" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT", - "optional": true - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -7123,9 +6899,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.4.tgz", + "integrity": "sha512-3+mMldrTAPdta5kjX2G2J7iX4zxtnwpdA8Tr2ZSjkyPSanvbZAcy6flmtnXbEybHrDcU9641lxrMfFuUxVz9vA==", "dev": true, "license": "ISC" }, @@ -7133,6 +6909,7 @@ "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, "license": "MIT", "dependencies": { "is-callable": "^1.2.7" @@ -7144,15 +6921,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/foreground-child": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", @@ -7244,18 +7012,6 @@ "node": ">= 0.6" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "license": "MIT", - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -7266,9 +7022,9 @@ } }, "node_modules/fs-extra": { - "version": "11.3.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", - "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", + "version": "11.3.4", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.4.tgz", + "integrity": "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", @@ -7283,6 +7039,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -7340,15 +7097,14 @@ } }, "node_modules/gaxios": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", - "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", "license": "Apache-2.0", "dependencies": { "extend": "^3.0.2", "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.2", - "rimraf": "^5.0.1" + "node-fetch": "^3.3.2" }, "engines": { "node": ">=18" @@ -7387,12 +7143,6 @@ "node": ">=6.9.0" } }, - "node_modules/get-assigned-identifiers": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", - "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", - "license": "Apache-2.0" - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -7402,6 +7152,19 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", + "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -7480,15 +7243,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/github-slugger": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", @@ -7539,12 +7293,12 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -7632,21 +7386,57 @@ } }, "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "16.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-16.1.1.tgz", + "integrity": "sha512-dW7vl+yiAJSp6aCekaVnVJxurRv7DCOLyXqEG3RYMYUg7AuJ2jCqPkZTA8ooqC2vtnkaMcV5WfFBMuEnTu1OQg==", "dev": true, "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "@sindresorhus/merge-streams": "^4.0.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.5", + "is-path-inside": "^4.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.4.0" }, "engines": { - "node": ">=10" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/globby/node_modules/is-path-inside": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-4.0.0.tgz", + "integrity": "sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globby/node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7660,23 +7450,37 @@ "license": "MIT" }, "node_modules/google-auth-library": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.5.0.tgz", - "integrity": "sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==", + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.1.tgz", + "integrity": "sha512-5awwuLrzNol+pFDmKJd0dKtZ0fPLAtoA5p7YO4ODsDu6ONJUVqbYwvv8y2ZBO5MBNp9TJXigB19710kYpBPdtA==", "license": "Apache-2.0", "dependencies": { "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", - "gaxios": "^7.0.0", - "gcp-metadata": "^8.0.0", - "google-logging-utils": "^1.0.0", - "gtoken": "^8.0.0", + "gaxios": "7.1.3", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", "jws": "^4.0.0" }, "engines": { "node": ">=18" } }, + "node_modules/google-auth-library/node_modules/gaxios": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.3.tgz", + "integrity": "sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2", + "rimraf": "^5.0.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/google-logging-utils": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", @@ -7720,28 +7524,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/gtoken": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-8.0.0.tgz", - "integrity": "sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==", - "license": "MIT", - "dependencies": { - "gaxios": "^7.0.0", - "jws": "^4.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/has": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", - "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -7769,6 +7551,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" @@ -7820,98 +7603,12 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "license": "MIT", - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hash-base": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.5.tgz", - "integrity": "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/hash-wasm": { "version": "4.12.0", "resolved": "https://registry.npmjs.org/hash-wasm/-/hash-wasm-4.12.0.tgz", "integrity": "sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==", "license": "MIT" }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "node_modules/hashery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.0.tgz", @@ -7937,17 +7634,6 @@ "node": ">= 0.4" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "license": "MIT", - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/hookified": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", @@ -7976,27 +7662,18 @@ "license": "MIT" }, "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==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-5.1.0.tgz", + "integrity": "sha512-n6l5uca7/y5joxZ3LUePhzmBFUJ+U2YWzhMa8XUTecSeSlQiZdF5XAd/Q3/WUl0VsXgUwWi8I7CNIwdI5WN1SQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=20.10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/http-errors": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", @@ -8031,12 +7708,6 @@ "node": ">= 14" } }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "license": "MIT" - }, "node_modules/https-proxy-agent": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", @@ -8082,26 +7753,6 @@ "integrity": "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==", "license": "Apache-2.0" }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -8112,12 +7763,6 @@ "node": ">= 4" } }, - "node_modules/ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", - "license": "ISC" - }, "node_modules/image-size": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", @@ -8178,6 +7823,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -8193,6 +7849,7 @@ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -8214,55 +7871,6 @@ "node": ">=10" } }, - "node_modules/inline-source-map": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.3.tgz", - "integrity": "sha512-1aVsPEsJWMJq/pdMU61CDlm1URcW702MTB4w9/zUjMus6H/Py8o7g68Pr9D4I6QluWGt/KdmswuRhaA05xVR1w==", - "license": "MIT", - "dependencies": { - "source-map": "~0.5.3" - } - }, - "node_modules/inline-source-map/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/insert-module-globals": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.1.tgz", - "integrity": "sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==", - "license": "MIT", - "dependencies": { - "acorn-node": "^1.5.2", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "JSONStream": "^1.0.3", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "undeclared-identifiers": "^1.1.2", - "xtend": "^4.0.0" - }, - "bin": { - "insert-module-globals": "bin/cmd.js" - } - }, - "node_modules/insert-module-globals/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -8287,18 +7895,6 @@ "node": ">= 0.10" } }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz", - "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/is-array-buffer": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", @@ -8360,18 +7956,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "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" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-boolean-object": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", @@ -8389,16 +7973,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "license": "MIT" - }, "node_modules/is-callable": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -8422,18 +8001,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz", - "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/is-data-view": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", @@ -8469,32 +8036,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-descriptor": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz", - "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8559,6 +8105,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -8597,6 +8144,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -8619,6 +8167,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -8742,6 +8300,7 @@ "version": "1.1.15", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, "license": "MIT", "dependencies": { "which-typed-array": "^1.1.16" @@ -8805,19 +8364,11 @@ "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", "license": "MIT" }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isarray": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, "license": "MIT" }, "node_modules/isexe": { @@ -8826,15 +8377,6 @@ "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/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -8958,7 +8500,6 @@ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "30.2.0", "@jest/types": "30.2.0", @@ -9590,7 +9131,6 @@ "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@acemir/cssom": "^0.9.31", "@asamuzakjp/dom-selector": "^6.8.1", @@ -9678,15 +9218,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha512-nKtD/Qxm7tWdZqJoldEC7fF0S41v0mWbeaXG3637stOWfyGxTgWTYE2wtfKmjzpvxv2MA2xzxsXOIiwUpkX6Qw==", - "license": "MIT", - "dependencies": { - "jsonify": "~0.0.0" - } - }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -9718,40 +9249,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.1.tgz", - "integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==", - "license": "Public Domain", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -9821,42 +9318,28 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/known-css-properties": { - "version": "0.37.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.37.0.tgz", - "integrity": "sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/labeled-stream-splicer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz", - "integrity": "sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "stream-splicer": "^2.0.0" - } - }, "node_modules/less": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/less/-/less-3.13.1.tgz", - "integrity": "sha512-SwA1aQXGUvp+P5XdZslUOhhLnClSLIjWvJhmd+Vgib5BFIr9lMNlQwmwUNOjXThF/A0x+MCYYPeWEfeWiLRnTw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/less/-/less-4.5.1.tgz", + "integrity": "sha512-UKgI3/KON4u6ngSsnDADsUERqhZknsVZbnuzlRZXLQCmfC/MDld42fTydUE9B+Mla1AL6SJ/Pp6SlEFi/AVGfw==", + "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { "copy-anything": "^2.0.1", - "tslib": "^1.10.0" + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" }, "bin": { "lessc": "bin/lessc" }, "engines": { - "node": ">=6" + "node": ">=14" }, "optionalDependencies": { "errno": "^0.1.1", @@ -9864,7 +9347,7 @@ "image-size": "~0.5.0", "make-dir": "^2.1.0", "mime": "^1.4.1", - "native-request": "^1.0.5", + "needle": "^3.1.0", "source-map": "~0.6.0" } }, @@ -9892,12 +9375,6 @@ "semver": "bin/semver" } }, - "node_modules/less/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "license": "0BSD" - }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -9929,30 +9406,6 @@ "dev": true, "license": "MIT" }, - "node_modules/livereload": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/livereload/-/livereload-0.9.3.tgz", - "integrity": "sha512-q7Z71n3i4X0R9xthAryBdNGVGAO2R5X+/xXpmKeuPMrteg+W2U8VusTKV3YiJbXZwKsOlFlHe+go6uSNjfxrZw==", - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.0", - "livereload-js": "^3.3.1", - "opts": ">= 1.2.0", - "ws": "^7.4.3" - }, - "bin": { - "livereload": "bin/livereload.js" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/livereload-js": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-3.4.1.tgz", - "integrity": "sha512-5MP0uUeVCec89ZbNOT/i97Mc+q3SxXmiUGhRFOTmhrGPn//uWVQdCvcLJDy64MSBR5MidFdOR7B9viumoavy6g==", - "license": "MIT" - }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -9978,12 +9431,6 @@ "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", "license": "MIT" }, - "node_modules/lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -10058,33 +9505,11 @@ "tmpl": "1.0.5" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "license": "MIT", - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/marked": { "version": "15.0.12", "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.12.tgz", "integrity": "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==", "license": "MIT", - "peer": true, "bin": { "marked": "bin/marked.js" }, @@ -10204,9 +9629,9 @@ } }, "node_modules/mathml-tag-names": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-4.0.0.tgz", + "integrity": "sha512-aa6AU2Pcx0VP/XWnh8IGL0SYSgQHDT6Ucror2j2mXeFAlN3ahaNs8EZtG1YiticMkSLj3Gt6VPFfZogt7G5iFQ==", "dev": true, "license": "MIT", "funding": { @@ -10214,17 +9639,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "license": "MIT", - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "node_modules/mdn-data": { "version": "2.12.2", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", @@ -10248,13 +9662,13 @@ "license": "MIT" }, "node_modules/meow": { - "version": "13.2.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", - "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-14.1.0.tgz", + "integrity": "sha512-EDYo6VlmtnumlcBCbh1gLJ//9jvM/ndXHfVXIFrZVr6fGcwTUyCTFNTLCKuY3ffbK8L/+3Mzqnd58RojiZqHVw==", "dev": true, "license": "MIT", "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10312,25 +9726,6 @@ "node": ">=8.6" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "license": "MIT" - }, "node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", @@ -10379,22 +9774,11 @@ "node": ">=6" } }, - "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/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "license": "MIT" - }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -10403,15 +9787,6 @@ "node": "*" } }, - "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/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", @@ -10421,88 +9796,6 @@ "node": ">=16 || 14 >=14.17" } }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "license": "MIT", - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-deep/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mixin-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" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, - "node_modules/module-deps": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.3.tgz", - "integrity": "sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==", - "license": "MIT", - "dependencies": { - "browser-resolve": "^2.0.0", - "cached-path-relative": "^1.0.2", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.2.0", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "JSONStream": "^1.0.3", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "module-deps": "bin/cmd.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/module-deps/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -10560,9 +9853,9 @@ } }, "node_modules/mongoose": { - "version": "9.2.1", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.2.1.tgz", - "integrity": "sha512-fmNLwgct5km7iL1MqvTMncarR1E1TIw2lmc9A4UoDVdS7AQe95K+DnRK0qATkSUdwUC9V/5wlDcqnkQQjbSRkA==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-9.2.4.tgz", + "integrity": "sha512-XNh+jiztVMddDFDCv8TWxVxi/rGx+0FfsK3Ftj6hcYzEmhTcos2uC144OJRmUFPHSu3hJr6Pgip++Ab2+Da35Q==", "license": "MIT", "dependencies": { "kareem": "3.2.0", @@ -10666,13 +9959,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/nan": { - "version": "2.25.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.25.0.tgz", - "integrity": "sha512-0M90Ag7Xn5KMLLZ7zliPWP3rT90P6PN+IzVFS0VqmnPktBk3700xUVv8Ikm9EUaUE5SDWdp/BIxdENzVznpm1g==", - "license": "MIT", - "optional": true - }, "node_modules/nanoid": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz", @@ -10691,91 +9977,6 @@ "node": "^18 || >=20" } }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/nanomatch/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/nanomatch/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" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/napi-postinstall": { "version": "0.3.4", "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", @@ -10792,13 +9993,6 @@ "url": "https://opencollective.com/napi-postinstall" } }, - "node_modules/native-request": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/native-request/-/native-request-1.1.2.tgz", - "integrity": "sha512-/etjwrK0J4Ebbcnt35VMWnfiUX/B04uwGJxyJInagxDqf2z5drSt/lsOvEMWGYunz1kaLZAFrV4NDAbOoDKvAQ==", - "license": "MIT", - "optional": true - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -10821,15 +10015,6 @@ "node": ">= 0.4.0" } }, - "node_modules/nconf/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/nconf/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -10861,18 +10046,6 @@ "node": ">=8" } }, - "node_modules/nconf/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" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/nconf/node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -10917,6 +10090,36 @@ "node": ">=10" } }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/negotiator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", @@ -10926,6 +10129,28 @@ "node": ">= 0.6" } }, + "node_modules/node": { + "version": "25.8.0", + "resolved": "https://registry.npmjs.org/node/-/node-25.8.0.tgz", + "integrity": "sha512-prXxZJ5522Khi5k5duwoxNPugh23L3V8Egf/dYt3/+/1FXuy1TqIHd8zHXseysEvVFf4Us5CFxylv2zu/wZz0g==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-bin-setup": "^1.0.0" + }, + "bin": { + "node": "bin/node" + }, + "engines": { + "npm": ">=5.0.0" + } + }, + "node_modules/node-bin-setup": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.1.4.tgz", + "integrity": "sha512-vWNHOne0ZUavArqPP5LJta50+S8R261Fr5SvGul37HbEDcowvLjwdvd0ZeSr0r2lTSrPxl6okq9QUw8BFGiAxA==", + "license": "ISC" + }, "node_modules/node-domexception": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", @@ -10991,82 +10216,16 @@ "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", "license": "MIT" }, - "node_modules/nodemon": { - "version": "2.0.22", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-2.0.22.tgz", - "integrity": "sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ==", - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.2", - "debug": "^3.2.7", - "ignore-by-default": "^1.0.1", - "minimatch": "^3.1.2", - "pstree.remy": "^1.1.8", - "semver": "^5.7.1", - "simple-update-notifier": "^1.0.7", - "supports-color": "^5.5.0", - "touch": "^3.1.0", - "undefsafe": "^2.0.5" - }, - "bin": { - "nodemon": "bin/nodemon.js" - }, - "engines": { - "node": ">=8.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/nodemon" - } - }, - "node_modules/nodemon/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/nodemon/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/nodemon/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/nodemon/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" - }, - "engines": { - "node": ">=4" - } - }, "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==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11094,32 +10253,6 @@ "node": ">=0.10.0" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "license": "MIT", - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -11136,27 +10269,17 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.assign": { "version": "4.1.7", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", @@ -11208,18 +10331,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/object.values": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", @@ -11294,27 +10405,6 @@ "node": ">= 0.8.0" } }, - "node_modules/opts": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opts/-/opts-2.0.2.tgz", - "integrity": "sha512-k41FwbcLnlgnFh69f4qdUfvDQ+5vaSDnVPFI/y5XuhKRq97EnVVneO9F1ESVCdiVu4fCS2L8usX3mU331hB7pg==", - "license": "BSD-2-Clause" - }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "license": "MIT" - }, - "node_modules/outpipe": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/outpipe/-/outpipe-1.1.1.tgz", - "integrity": "sha512-BnNY/RwnDrkmQdUa9U+OfN/Y7AWmKuUPCCd+hbRclZnnANvYpO72zp/a6Q4n829hPbdqEac31XCcsvlEvb+rtA==", - "license": "MIT", - "dependencies": { - "shell-quote": "^1.4.2" - } - }, "node_modules/own-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", @@ -11394,12 +10484,6 @@ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "license": "(MIT AND Zlib)" - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -11413,31 +10497,6 @@ "node": ">=6" } }, - "node_modules/parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==", - "license": "MIT", - "dependencies": { - "path-platform": "~0.11.15" - } - }, - "node_modules/parse-asn1": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz", - "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==", - "license": "ISC", - "dependencies": { - "asn1.js": "^4.10.1", - "browserify-aes": "^1.2.0", - "evp_bytestokey": "^1.0.3", - "pbkdf2": "^3.1.5", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -11457,6 +10516,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/parse5": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", @@ -11479,27 +10547,6 @@ "node": ">= 0.8" } }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "license": "MIT" - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==", - "license": "MIT" - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11514,6 +10561,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -11534,15 +10582,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, - "node_modules/path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/path-scurry": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", @@ -11575,33 +10614,6 @@ "url": "https://opencollective.com/express" } }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pbkdf2": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", - "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", - "license": "MIT", - "dependencies": { - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "ripemd160": "^2.0.3", - "safe-buffer": "^5.2.1", - "sha.js": "^2.4.12", - "to-buffer": "^1.2.1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -11612,6 +10624,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "license": "MIT", "engines": { "node": ">=8.6" @@ -11653,29 +10666,20 @@ "node": ">=8" } }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/possible-typed-array-names": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" } }, "node_modules/postcss": { - "version": "8.5.6", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", - "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", - "dev": true, + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "funding": [ { "type": "opencollective", @@ -11691,7 +10695,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -11714,13 +10717,6 @@ "postcss": "^8.3.5" } }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz", - "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==", - "dev": true, - "license": "MIT" - }, "node_modules/postcss-safe-parser": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz", @@ -11754,7 +10750,6 @@ "integrity": "sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -11769,6 +10764,7 @@ "integrity": "sha512-Mn8KJ45HNNG6JBpBizXcyf6LqY/qyqetGcou/nprDnFwBFBLGj0j/sNKV2lj2KMOVOwdXu14aEzqJv8CIV6e8g==", "dev": true, "license": "MIT", + "peer": true, "peerDependencies": { "postcss": "^8.4.20" } @@ -11784,7 +10780,6 @@ "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, "funding": [ { "type": "github", @@ -11837,27 +10832,11 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "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/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", - "peer": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -11890,32 +10869,6 @@ "license": "MIT", "optional": true }, - "node_modules/pstree.remy": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz", - "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", - "license": "MIT" - }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "license": "MIT", - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.3", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", - "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", - "license": "MIT" - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -11970,14 +10923,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -11999,25 +10944,6 @@ ], "license": "MIT" }, - "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/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "license": "MIT", - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -12043,36 +10969,30 @@ } }, "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", + "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", - "peer": true, - "dependencies": { - "loose-envify": "^1.1.0" - }, "engines": { "node": ">=0.10.0" } }, "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", + "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", - "peer": true, "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" + "scheduler": "^0.27.0" }, "peerDependencies": { - "react": "^18.3.1" + "react": "^19.2.4" } }, "node_modules/react-frame-component": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-4.1.3.tgz", - "integrity": "sha512-4PurhctiqnmC1F5prPZ+LdsalH7pZ3SFA5xoc0HBe8mSHctdLLt4Cr2WXfXOoajHBYq/yiipp9zOgx+vy8GiEA==", + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/react-frame-component/-/react-frame-component-5.2.7.tgz", + "integrity": "sha512-ROjHtSLoSVYUBfTieazj/nL8jIX9rZFmHC0yXEU+dx6Y82OcBEGgU9o7VyHMrBFUN9FuQ849MtIPNNLsb4krbg==", "license": "MIT", "peerDependencies": { "prop-types": "^15.5.9", @@ -12087,10 +11007,19 @@ "dev": true, "license": "MIT" }, + "node_modules/react-refresh": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.18.0.tgz", + "integrity": "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-router": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.0.tgz", - "integrity": "sha512-PZgus8ETambRT17BUm/LL8lX3Of+oiLaPuVTRH3l1eLvSPpKO3AvhAEb5N7ihAFZQrYDqkvvWfFh9p0z9VsjLw==", + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.13.1.tgz", + "integrity": "sha512-td+xP4X2/6BJvZoX6xw++A2DdEi++YypA69bJUV5oVvqf6/9/9nNlD70YO1e9d3MyamJEBQFEzk6mbfDYbqrSA==", "license": "MIT", "dependencies": { "cookie": "^1.0.1", @@ -12122,63 +11051,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/read-only-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==", - "license": "MIT", - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "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", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/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/readable-stream/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/readable-stream/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/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" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -12220,56 +11092,6 @@ "node": ">=4" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regex-not/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" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/regexp.prototype.flags": { "version": "1.5.4", "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", @@ -12326,30 +11148,6 @@ "regjsparser": "bin/parser" } }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", - "license": "ISC" - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -12412,22 +11210,6 @@ "node": ">=8" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "license": "MIT" - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -12454,32 +11236,48 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", - "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "license": "MIT", "dependencies": { - "hash-base": "^3.1.2", - "inherits": "^2.0.4" + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/ripemd160/node_modules/hash-base": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", - "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^2.3.8", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.1" + "node": ">=18.0.0", + "npm": ">=8.0.0" }, - "engines": { - "node": ">= 0.8" + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" } }, "node_modules/romans": { @@ -12585,15 +11383,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==", - "license": "MIT", - "dependencies": { - "ret": "~0.1.10" - } - }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", @@ -12627,6 +11416,16 @@ "truncate-utf8-bytes": "^1.0.0" } }, + "node_modules/sax": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", + "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "license": "BlueOak-1.0.0", + "optional": true, + "engines": { + "node": ">=11.0.0" + } + }, "node_modules/saxes": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", @@ -12641,13 +11440,10 @@ } }, "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "license": "MIT" }, "node_modules/secure-keys": { "version": "1.0.0", @@ -12719,6 +11515,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", @@ -12763,81 +11560,12 @@ "node": ">= 0.4" } }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/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" - }, - "engines": { - "node": ">=0.10.0" - } - }, "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/sha.js": { - "version": "2.4.12", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", - "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", - "license": "(MIT AND BSD-3-Clause)", - "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.0" - }, - "bin": { - "sha.js": "bin.js" - }, - "engines": { - "node": ">= 0.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha512-UTzHm/+AzKfO9RgPgRpDIuMSNie1ubXRaljjlhFMNGYoG7z+rm9AHLPMf70R7887xboDH9Q+5YQbWKObFHEAtw==", - "license": "MIT", - "dependencies": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" - } - }, - "node_modules/shasum-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/shasum-object/-/shasum-object-1.0.1.tgz", - "integrity": "sha512-SsC+1tW7XKQ/94D4k1JhLmjDFpVGET/Nf54jVDtbavbALf8Zhp0Td9zTlxScjMW6nbEIrpADtPWfLk9iCXzHDQ==", - "license": "Apache-2.0", - "dependencies": { - "fast-safe-stringify": "^2.0.7" - }, - "bin": { - "shasum-object": "bin.js" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -12859,18 +11587,6 @@ "node": ">=8" } }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/side-channel": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", @@ -12961,47 +11677,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-update-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", - "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", - "license": "MIT", - "dependencies": { - "semver": "~7.0.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -13030,116 +11705,11 @@ "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "license": "MIT", - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "license": "MIT", - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/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/snapdragon/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/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "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==", + "devOptional": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -13149,26 +11719,11 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "license": "MIT", - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -13180,13 +11735,6 @@ "source-map": "^0.6.0" } }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "license": "MIT" - }, "node_modules/sparse-bitfield": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz", @@ -13196,55 +11744,6 @@ "memory-pager": "^1.0.2" } }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/split-string/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" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", @@ -13275,19 +11774,6 @@ "node": ">=8" } }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==", - "license": "MIT", - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/statuses": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", @@ -13311,71 +11797,6 @@ "node": ">= 0.4" } }, - "node_modules/stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "license": "MIT", - "dependencies": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==", - "license": "MIT", - "dependencies": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "license": "MIT", - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, - "node_modules/stream-http/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", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.1.tgz", - "integrity": "sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" - } - }, - "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-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -13390,29 +11811,6 @@ "node": ">=10" } }, - "node_modules/string-length/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/string-length/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -13445,31 +11843,37 @@ "node": ">=8" } }, - "node_modules/string-width-cjs/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/string-width-cjs/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/string-width-cjs/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==", + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, "node_modules/string.prototype.matchall": { @@ -13571,22 +11975,6 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", @@ -13598,11 +11986,15 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs/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==", + "node_modules/strip-ansi-cjs": { + "name": "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" + }, "engines": { "node": ">=8" } @@ -13648,9 +12040,9 @@ "license": "ISC" }, "node_modules/stylelint": { - "version": "16.26.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.26.1.tgz", - "integrity": "sha512-v20V59/crfc8sVTAtge0mdafI3AdnzQ2KsWe6v523L4OA1bJO02S7MO2oyXDCS6iWb9ckIPnqAFVItqSBQr7jw==", + "version": "17.4.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-17.4.0.tgz", + "integrity": "sha512-3kQ2/cHv3Zt8OBg+h2B8XCx9evEABQIrv4hh3uXahGz/ZEHrTR80zxBiK2NfXNaSoyBzxO1pjsz1Vhdzwn5XSw==", "dev": true, "funding": [ { @@ -13663,53 +12055,50 @@ } ], "license": "MIT", - "peer": true, "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.5", - "@csstools/css-syntax-patches-for-csstree": "^1.0.19", - "@csstools/css-tokenizer": "^3.0.4", - "@csstools/media-query-list-parser": "^4.0.3", - "@csstools/selector-specificity": "^5.0.0", - "@dual-bundle/import-meta-resolve": "^4.2.1", - "balanced-match": "^2.0.0", + "@csstools/css-calc": "^3.1.1", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-syntax-patches-for-csstree": "^1.0.27", + "@csstools/css-tokenizer": "^4.0.0", + "@csstools/media-query-list-parser": "^5.0.0", + "@csstools/selector-resolve-nested": "^4.0.0", + "@csstools/selector-specificity": "^6.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", - "css-functions-list": "^3.2.3", + "css-functions-list": "^3.3.3", "css-tree": "^3.1.0", "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^11.1.1", + "file-entry-cache": "^11.1.2", "global-modules": "^2.0.0", - "globby": "^11.1.0", + "globby": "^16.1.0", "globjoin": "^0.1.4", - "html-tags": "^3.3.1", + "html-tags": "^5.1.0", "ignore": "^7.0.5", + "import-meta-resolve": "^4.2.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.37.0", - "mathml-tag-names": "^2.1.3", - "meow": "^13.2.0", + "mathml-tag-names": "^4.0.0", + "meow": "^14.0.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.5.6", - "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", - "postcss-selector-parser": "^7.1.0", + "postcss-selector-parser": "^7.1.1", "postcss-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "supports-hyperlinks": "^3.2.0", + "string-width": "^8.1.1", + "supports-hyperlinks": "^4.4.0", "svg-tags": "^1.0.0", "table": "^6.9.0", - "write-file-atomic": "^5.0.1" + "write-file-atomic": "^7.0.0" }, "bin": { "stylelint": "bin/stylelint.mjs" }, "engines": { - "node": ">=18.12.0" + "node": ">=20.19.0" } }, "node_modules/stylelint-config-recess-order": { @@ -13724,9 +12113,9 @@ } }, "node_modules/stylelint-config-recommended": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-17.0.0.tgz", - "integrity": "sha512-WaMSdEiPfZTSFVoYmJbxorJfA610O0tlYuU2aEwY33UQhSPgFbClrVJYWvy3jGJx+XW37O+LyNLiZOEXhKhJmA==", + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-18.0.0.tgz", + "integrity": "sha512-mxgT2XY6YZ3HWWe3Di8umG6aBmWmHTblTgu/f10rqFXnyWxjKWwNdjSWkgkwCtxIKnqjSJzvFmPT5yabVIRxZg==", "dev": true, "funding": [ { @@ -13740,10 +12129,10 @@ ], "license": "MIT", "engines": { - "node": ">=18.12.0" + "node": ">=20.19.0" }, "peerDependencies": { - "stylelint": "^16.23.0" + "stylelint": "^17.0.0" } }, "node_modules/stylelint-order": { @@ -13765,29 +12154,18 @@ } }, "node_modules/stylelint/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==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/stylelint/node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true, - "license": "MIT" - }, - "node_modules/stylelint/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==", - "dev": true, - "license": "MIT" - }, "node_modules/stylelint/node_modules/file-entry-cache": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.2.tgz", @@ -13821,40 +12199,49 @@ } }, "node_modules/stylelint/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==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz", + "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=8" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/stylelint/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==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/subarg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==", - "license": "MIT", + "node_modules/stylelint/node_modules/write-file-atomic": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-7.0.1.tgz", + "integrity": "sha512-OTIk8iR8/aCRWBqvxrzxR0hgxWpnYBblY1S5hDWBQfk/VFmJwzmJgQFN3WsoUKHISv2eAwe+PpbUzyL1CKTLXg==", + "dev": true, + "license": "ISC", "dependencies": { - "minimist": "^1.1.0" + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/superagent": { @@ -13928,22 +12315,48 @@ } }, "node_modules/supports-hyperlinks": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz", - "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-4.4.0.tgz", + "integrity": "sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" + "has-flag": "^5.0.1", + "supports-color": "^10.2.2" }, "engines": { - "node": ">=14.18" + "node": ">=20" }, "funding": { "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1" } }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-5.0.1.tgz", + "integrity": "sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", + "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, "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", @@ -13985,15 +12398,6 @@ "url": "https://opencollective.com/synckit" } }, - "node_modules/syntax-error": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", - "license": "MIT", - "dependencies": { - "acorn-node": "^1.2.0" - } - }, "node_modules/table": { "version": "6.9.0", "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", @@ -14028,16 +12432,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/table/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -14067,19 +12461,6 @@ "node": ">=8" } }, - "node_modules/table/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -14117,38 +12498,17 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "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==", + "dev": true, "license": "MIT" }, - "node_modules/through2": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", - "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "2 || 3" - } - }, - "node_modules/timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==", - "dependencies": { - "process": "~0.11.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -14165,7 +12525,6 @@ "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, "license": "MIT", "engines": { "node": ">=12.0.0" @@ -14183,9 +12542,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -14194,22 +12551,22 @@ } }, "node_modules/tldts": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.23.tgz", - "integrity": "sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.24.tgz", + "integrity": "sha512-1r6vQTTt1rUiJkI5vX7KG8PR342Ru/5Oh13kEQP2SMbRSZpOey9SrBe27IDxkoWulx8ShWu4K6C0BkctP8Z1bQ==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.0.23" + "tldts-core": "^7.0.24" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.0.23", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.23.tgz", - "integrity": "sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==", + "version": "7.0.24", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.24.tgz", + "integrity": "sha512-pj7yygNMoMRqG7ML2SDQ0xNIOfN3IBDUcPVM2Sg6hP96oFNN2nqnzHreT3z9xLq85IWJyNTvD38O002DdOrPMw==", "dev": true, "license": "MIT" }, @@ -14220,63 +12577,11 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/to-buffer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", - "license": "MIT", - "dependencies": { - "isarray": "^2.0.5", - "safe-buffer": "^5.2.1", - "typed-array-buffer": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "license": "MIT", - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "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==", + "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -14285,69 +12590,6 @@ "node": ">=8.0" } }, - "node_modules/to-regex/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/to-regex/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex/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" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -14357,15 +12599,6 @@ "node": ">=0.6" } }, - "node_modules/touch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz", - "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==", - "license": "ISC", - "bin": { - "nodetouch": "bin/nodetouch.js" - } - }, "node_modules/tough-cookie": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", @@ -14418,15 +12651,8 @@ "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, "license": "0BSD" }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "license": "MIT" - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14481,6 +12707,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.3", @@ -14554,12 +12781,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "license": "MIT" - }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -14575,15 +12796,6 @@ "node": ">=14.17" } }, - "node_modules/umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "license": "MIT", - "bin": { - "umd": "bin/cli.js" - } - }, "node_modules/unbox-primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", @@ -14603,28 +12815,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/undeclared-identifiers": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", - "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", - "license": "Apache-2.0", - "dependencies": { - "acorn-node": "^1.3.0", - "dash-ast": "^1.0.0", - "get-assigned-identifiers": "^1.2.0", - "simple-concat": "^1.0.0", - "xtend": "^4.0.1" - }, - "bin": { - "undeclared-identifiers": "bin.js" - } - }, - "node_modules/undefsafe": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz", - "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==", - "license": "MIT" - }, "node_modules/undici": { "version": "7.22.0", "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz", @@ -14639,7 +12829,7 @@ "version": "7.18.2", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", - "dev": true, + "devOptional": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -14682,19 +12872,17 @@ "node": ">=4" } }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "node_modules/unicorn-magic": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.4.0.tgz", + "integrity": "sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==", + "dev": true, "license": "MIT", - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/universalify": { @@ -14750,70 +12938,6 @@ "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" } }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==", - "license": "MIT", - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "license": "MIT", - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "license": "MIT", - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/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/upath": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "license": "MIT", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -14854,74 +12978,25 @@ "punycode": "^2.1.0" } }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "license": "MIT" - }, - "node_modules/url": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.4.tgz", - "integrity": "sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==", - "license": "MIT", - "dependencies": { - "punycode": "^1.4.1", - "qs": "^6.12.3" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/url-template": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==", "license": "BSD" }, - "node_modules/url/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/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/utf8-byte-length": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz", "integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==", "license": "(WTFPL OR MIT)" }, - "node_modules/util": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", - "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", - "license": "MIT", - "dependencies": { - "inherits": "2.0.3" - } - }, "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==", + "dev": true, "license": "MIT" }, - "node_modules/util/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/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -14946,58 +13021,108 @@ "node": ">= 0.8" } }, - "node_modules/vitreum": { - "version": "6.0.4", - "resolved": "git+https://git@github.com/calculuschild/vitreum.git#929c351881c4229550374421c7e2890a94f4dca7", - "hasInstallScript": true, + "node_modules/vite": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "license": "MIT", "dependencies": { - "browserify": "^16.5.0", - "fs-extra": "^9.0.1", - "livereload": "^0.9.1", - "nodemon": "^2.0.2", - "source-map-support": "^0.5.16", - "through2": "^3.0.1", - "watchify": "^3.11.1" + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" }, - "peerDependencies": { - "@babel/core": "^7.9.0", - "@babel/preset-react": "^7.9.4", - "less": "^3.11.1", - "react": "^18.3.1", - "react-dom": "^18.3.1" - } - }, - "node_modules/vitreum/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", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "bin": { + "vite": "bin/vite.js" }, "engines": { - "node": ">=10" + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } } }, - "node_modules/vitreum/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==", + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "license": "MIT" + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", @@ -15022,314 +13147,6 @@ "makeerror": "1.0.12" } }, - "node_modules/watchify": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/watchify/-/watchify-3.11.1.tgz", - "integrity": "sha512-WwnUClyFNRMB2NIiHgJU9RQPQNqVeFk7OmZaWf5dC5EnNa0Mgr7imBydbaJ7tGTuPM2hz1Cb4uiBvK9NVxMfog==", - "license": "MIT", - "dependencies": { - "anymatch": "^2.0.0", - "browserify": "^16.1.0", - "chokidar": "^2.1.1", - "defined": "^1.0.0", - "outpipe": "^1.1.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" - }, - "bin": { - "watchify": "bin/cmd.js" - } - }, - "node_modules/watchify/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "license": "ISC", - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "node_modules/watchify/node_modules/anymatch/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", - "license": "MIT", - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "license": "MIT", - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/chokidar": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", - "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", - "license": "MIT", - "dependencies": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - }, - "optionalDependencies": { - "fsevents": "^1.2.7" - } - }, - "node_modules/watchify/node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "license": "MIT", - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "license": "MIT", - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/watchify/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "license": "ISC", - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/watchify/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==", - "license": "MIT", - "dependencies": { - "binary-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-descriptor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz", - "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==", - "license": "MIT", - "dependencies": { - "is-accessor-descriptor": "^1.0.1", - "is-data-descriptor": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/watchify/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "license": "MIT", - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "license": "MIT", - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/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" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "license": "MIT", - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/micromatch/node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "license": "MIT", - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/watchify/node_modules/readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/watchify/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/watchify/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==", - "license": "MIT", - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/web-streams-polyfill": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", @@ -15460,6 +13277,7 @@ "version": "1.1.20", "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", + "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", @@ -15522,15 +13340,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs/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/wrap-ansi-cjs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -15551,16 +13360,16 @@ "node": ">=8" } }, - "node_modules/wrap-ansi-cjs/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==", + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { @@ -15575,6 +13384,21 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -15601,27 +13425,6 @@ "integrity": "sha512-LhQ68uUnzHH0bwm/QiGA9JwqgadSDOwqB2AIs/LBsrOY6ScqVXKRN2slTCeKAhstDBJ/Of/Yxcjn0pnQmVlmtg==", "license": "MIT" }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/xml-name-validator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", @@ -15639,15 +13442,6 @@ "dev": true, "license": "MIT" }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -15692,16 +13486,6 @@ "node": ">=12" } }, - "node_modules/yargs/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/yargs/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -15724,19 +13508,6 @@ "node": ">=8" } }, - "node_modules/yargs/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==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 7004ec51d..f6ff1ba03 100644 --- a/package.json +++ b/package.json @@ -4,18 +4,16 @@ "version": "3.20.1", "type": "module", "engines": { - "npm": "^10.8.x", - "node": "^20.18.x" + "npm": ">=10.8 <12", + "node": ">=20.18 <25" }, "repository": { "type": "git", "url": "git://github.com/naturalcrit/homebrewery.git" }, "scripts": { - "dev": "node --experimental-require-module scripts/dev.js", - "quick": "node --experimental-require-module scripts/quick.js", - "build": "node --experimental-require-module scripts/buildHomebrew.js && node --experimental-require-module scripts/buildAdmin.js", - "builddev": "node --experimental-require-module scripts/buildHomebrew.js --dev", + "start": "node server.js", + "build": "vite build", "lint": "eslint --fix", "lint:dry": "eslint", "stylelint": "stylelint --fix **/*.{less}", @@ -44,7 +42,6 @@ "phb": "node --experimental-require-module scripts/phb.js", "prod": "set NODE_ENV=production && npm run build", "postinstall": "npm run build", - "start": "node --experimental-require-module server.js", "docker:build": "docker build -t ${DOCKERID}/homebrewery:$npm_package_version .", "docker:publish": "docker login && docker push ${DOCKERID}/homebrewery:$npm_package_version" }, @@ -93,10 +90,11 @@ "@babel/plugin-transform-runtime": "^7.29.0", "@babel/preset-env": "^7.29.0", "@babel/preset-react": "^7.28.5", - "@babel/runtime": "^7.28.4", + "@babel/runtime": "^7.28.6", "@dmsnell/diff-match-patch": "^1.1.0", "@googleapis/drive": "^20.1.0", "@sanity/diff-match-patch": "^3.2.0", + "@vitejs/plugin-react": "^5.1.2", "body-parser": "^2.2.0", "classnames": "^2.5.1", "codemirror": "^5.65.6", @@ -105,7 +103,6 @@ "cors": "^2.8.5", "create-react-class": "^15.7.0", "dedent": "^1.7.1", - "expr-eval": "^2.0.2", "express": "^5.1.0", "express-async-handler": "^1.2.0", "express-static-gzip": "3.0.0", @@ -115,7 +112,7 @@ "idb-keyval": "^6.2.2", "js-yaml": "^4.1.1", "jwt-simple": "^0.5.6", - "less": "^3.13.1", + "less": "^4.5.1", "lodash": "^4.17.21", "marked": "15.0.12", "marked-alignment-paragraphs": "^1.0.0", @@ -132,21 +129,19 @@ "mongoose": "^9.2.1", "nanoid": "5.1.6", "nconf": "^0.13.0", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "react-frame-component": "^4.1.3", - "react-router": "^7.9.6", - "romans": "^3.1.0", + "node": "^25.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-frame-component": "^5.2.7", + "react-router": "^7.13.1", "sanitize-filename": "1.6.3", - "superagent": "^10.2.1", - "vitreum": "git+https://git@github.com/calculuschild/vitreum.git", - "written-number": "^0.11.1" + "superagent": "^10.2.1" }, "devDependencies": { - "@stylistic/stylelint-plugin": "^4.0.0", + "@stylistic/stylelint-plugin": "^5.0.1", "babel-jest": "^30.2.0", "babel-plugin-transform-import-meta": "^2.3.3", - "eslint": "^9.39.1", + "eslint": "9.7", "eslint-plugin-jest": "^29.1.0", "eslint-plugin-react": "^7.37.5", "globals": "^16.4.0", @@ -155,9 +150,10 @@ "jsdom": "^28.1.0", "jsdom-global": "^3.0.2", "postcss-less": "^6.0.0", - "stylelint": "^16.25.0", - "stylelint-config-recess-order": "^7.3.0", - "stylelint-config-recommended": "^17.0.0", - "supertest": "^7.1.4" + "stylelint": "^17.4.0", + "stylelint-config-recess-order": "^7.6.1", + "stylelint-config-recommended": "^18.0.0", + "supertest": "^7.1.4", + "vite": "^7.3.1" } } diff --git a/scripts/buildAdmin.js b/scripts/buildAdmin.js deleted file mode 100644 index 9c77315ef..000000000 --- a/scripts/buildAdmin.js +++ /dev/null @@ -1,32 +0,0 @@ - -import fs from 'fs-extra'; -import Proj from './project.json' with { type: 'json' }; -import vitreum from 'vitreum'; -const { pack } = vitreum; - -import lessTransform from 'vitreum/transforms/less.js'; -import assetTransform from 'vitreum/transforms/asset.js'; - -const isDev = !!process.argv.find((arg)=>arg=='--dev'); - -const transforms = { - '.less' : lessTransform, - '*' : assetTransform('./build') -}; - -const build = async ({ bundle, render, ssr })=>{ - const css = await lessTransform.generate({ paths: './shared' }); - await fs.outputFile('./build/admin/bundle.css', css); - await fs.outputFile('./build/admin/bundle.js', bundle); - await fs.outputFile('./build/admin/ssr.cjs', ssr); -}; - -fs.emptyDirSync('./build/admin'); -pack('./client/admin/admin.jsx', { - paths : ['./shared'], - libs : Proj.libs, - dev : isDev && build, - transforms -}) - .then(build) - .catch(console.error); diff --git a/scripts/buildHomebrew.js b/scripts/buildHomebrew.js deleted file mode 100644 index 4d55a4176..000000000 --- a/scripts/buildHomebrew.js +++ /dev/null @@ -1,169 +0,0 @@ -import fs from 'fs-extra'; -import zlib from 'zlib'; -import Proj from './project.json' with { type: 'json' }; -import vitreum from 'vitreum'; -const { pack, watchFile, livereload } = vitreum; - -import lessTransform from 'vitreum/transforms/less.js'; -import assetTransform from 'vitreum/transforms/asset.js'; -import babel from '@babel/core'; -import babelConfig from '../babel.config.json' with { type : 'json' }; -import less from 'less'; - -const isDev = !!process.argv.find((arg)=>arg === '--dev'); - -const babelify = async (code)=>(await babel.transformAsync(code, babelConfig)).code; - -const transforms = { - '.js' : (code, filename, opts)=>babelify(code), - '.jsx' : (code, filename, opts)=>babelify(code), - '.less' : lessTransform, - '*' : assetTransform('./build') -}; - -const build = async ({ bundle, render, ssr })=>{ - const css = await lessTransform.generate({ paths: './shared' }); - //css = `@layer bundle {\n${css}\n}`; - await fs.outputFile('./build/homebrew/bundle.css', css); - await fs.outputFile('./build/homebrew/bundle.js', bundle); - await fs.outputFile('./build/homebrew/ssr.cjs', ssr); - - await fs.copy('./client/homebrew/favicon.ico', './build/assets/favicon.ico'); - - //compress files in production - if(!isDev){ - await fs.outputFile('./build/homebrew/bundle.css.br', zlib.brotliCompressSync(css)); - await fs.outputFile('./build/homebrew/bundle.js.br', zlib.brotliCompressSync(bundle)); - await fs.outputFile('./build/homebrew/ssr.js.br', zlib.brotliCompressSync(ssr)); - } else { - await fs.remove('./build/homebrew/bundle.css.br'); - await fs.remove('./build/homebrew/bundle.js.br'); - await fs.remove('./build/homebrew/ssr.js.br'); - } -}; - -fs.emptyDirSync('./build'); - - -(async ()=>{ - - //v==----------------------------- COMPILE THEMES --------------------------------==v// - - // Update list of all Theme files - const themes = { Legacy: {}, V3: {} }; - - let themeFiles = fs.readdirSync('./themes/Legacy'); - for (const dir of themeFiles) { - const themeData = JSON.parse(fs.readFileSync(`./themes/Legacy/${dir}/settings.json`).toString()); - themeData.path = dir; - themes.Legacy[dir] = (themeData); - //fs.copy(`./themes/Legacy/${dir}/dropdownTexture.png`, `./build/themes/Legacy/${dir}/dropdownTexture.png`); - const src = `./themes/Legacy/${dir}/style.less`; - ((outputDirectory)=>{ - less.render(fs.readFileSync(src).toString(), { - compress : !isDev - }, function(e, output) { - fs.outputFile(outputDirectory, output.css); - }); - })(`./build/themes/Legacy/${dir}/style.css`); - - } - - themeFiles = fs.readdirSync('./themes/V3'); - for (const dir of themeFiles) { - const themeData = JSON.parse(fs.readFileSync(`./themes/V3/${dir}/settings.json`).toString()); - themeData.path = dir; - themes.V3[dir] = (themeData); - fs.copy(`./themes/V3/${dir}/dropdownTexture.png`, `./build/themes/V3/${dir}/dropdownTexture.png`); - fs.copy(`./themes/V3/${dir}/dropdownPreview.png`, `./build/themes/V3/${dir}/dropdownPreview.png`); - const src = `./themes/V3/${dir}/style.less`; - ((outputDirectory)=>{ - less.render(fs.readFileSync(src).toString(), { - compress : !isDev - }, function(e, output) { - fs.outputFile(outputDirectory, output.css); - }); - })(`./build/themes/V3/${dir}/style.css`); - } - - await fs.outputFile('./themes/themes.json', JSON.stringify(themes, null, 2)); - - // await less.render(lessCode, { - // compress : !dev, - // sourceMap : (dev ? { - // sourceMapFileInline: true, - // outputSourceFiles: true - // } : false), - // }) - - // Move assets - await fs.copy('./themes/fonts', './build/fonts'); - await fs.copy('./themes/assets', './build/assets'); - await fs.copy('./client/icons', './build/icons'); - - //v==---------------------------MOVE CM EDITOR THEMES -----------------------------==v// - - const editorThemesBuildDir = './build/homebrew/cm-themes'; - await fs.copy('./node_modules/codemirror/theme', editorThemesBuildDir); - await fs.copy('./themes/codeMirror/customThemes', editorThemesBuildDir); - const editorThemeFiles = fs.readdirSync(editorThemesBuildDir); - - const editorThemeFile = './themes/codeMirror/editorThemes.json'; - if(fs.existsSync(editorThemeFile)) fs.rmSync(editorThemeFile); - const stream = fs.createWriteStream(editorThemeFile, { flags: 'a' }); - stream.write('[\n"default"'); - - for (const themeFile of editorThemeFiles) { - stream.write(`,\n"${themeFile.slice(0, -4)}"`); - } - stream.write('\n]\n'); - stream.end(); - - - await fs.copy('./themes/codeMirror', './build/homebrew/codeMirror'); - - //v==----------------------------- BUNDLE PACKAGES --------------------------------==v// - - const bundles = await pack('./client/homebrew/homebrew.jsx', { - paths : ['./shared', './'], - libs : Proj.libs, - dev : isDev && build, - transforms - }); - build(bundles); - - // Possible method for generating separate bundles for theme snippets: factor-bundle first sending all common files to bundle.js, then again using default settings, keeping only snippet bundles - // await fs.outputFile('./build/junk.js', ''); - // await fs.outputFile('./build/themes/Legacy/5ePHB/snippets.js', ''); - // - // const files = ['./client/homebrew/homebrew.jsx','./themes/Legacy/5ePHB/snippets.js']; - // - // bundles = await pack(files, { - // dedupe: false, - // plugin : [['factor-bundle', { outputs: [ './build/junk.js','./build/themes/Legacy/5ePHB/snippets.js'], threshold : function(row, groups) { - // console.log(groups); - // if (groups.some(group => /.*homebrew.jsx$/.test(group))) { - // console.log("found homebrewery") - // return true; - // } - // return this._defaultThreshold(row, groups); - // }}]], - // paths : ['./shared','./','./build'], - // libs : Proj.libs, - // dev : isDev && build, - // transforms - // }); - // build(bundles); - // - - //In development, set up LiveReload (refreshes browser), and Nodemon (restarts server) - if(isDev){ - livereload('./build'); // Install the Chrome extension LiveReload to automatically refresh the browser - watchFile('./server.js', { // Restart server when change detected to this file or any nested directory from here - ignore : ['./build', './client', './themes'], // Ignore folders that are not running server code / avoids unneeded restarts - ext : 'js json' // Extensions to watch (only .js/.json by default) - //watch : ['./server', './themes'], // Watch additional folders if needed - }); - } - -})().catch(console.error); \ No newline at end of file diff --git a/scripts/dev.js b/scripts/dev.js deleted file mode 100644 index 45f6c3d99..000000000 --- a/scripts/dev.js +++ /dev/null @@ -1,22 +0,0 @@ -const label = 'dev'; -console.time(label); - -const jsx = require('vitreum/steps/jsx.watch.js'); -const less = require('vitreum/steps/less.watch.js'); -const assets = require('vitreum/steps/assets.watch.js'); -const server = require('vitreum/steps/server.watch.js'); -const livereload = require('vitreum/steps/livereload.js'); - -const Proj = require('./project.json'); - -Promise.resolve() - .then(()=>jsx('homebrew', './client/homebrew/homebrew.jsx', { libs: Proj.libs, shared: ['./shared'] })) - .then((deps)=>less('homebrew', { shared: ['./shared'] }, deps)) - .then(()=>jsx('admin', './client/admin/admin.jsx', { libs: Proj.libs, shared: ['./shared'] })) - .then((deps)=>less('admin', { shared: ['./shared'] }, deps)) - - .then(()=>assets(Proj.assets, ['./shared', './client'])) - .then(()=>livereload()) - .then(()=>server('./server.js', ['server'])) - .then(console.timeEnd.bind(console, label)) - .catch(console.error); \ No newline at end of file diff --git a/scripts/quick.js b/scripts/quick.js deleted file mode 100644 index e763d85f7..000000000 --- a/scripts/quick.js +++ /dev/null @@ -1,17 +0,0 @@ -const label = 'quick'; -console.time(label); - -const jsx = require('vitreum/steps/jsx.js').partial; -const less = require('vitreum/steps/less.js').partial; -const server = require('vitreum/steps/server.watch.js').partial; - -const Proj = require('./project.json'); - -Promise.resolve() - .then(jsx('homebrew', './client/homebrew/homebrew.jsx', Proj.libs, ['./shared'])) - .then(less('homebrew', ['./shared'])) - .then(jsx('admin', './client/admin/admin.jsx', Proj.libs, ['./shared'])) - .then(less('admin', ['./shared'])) - .then(server('./server.js', ['server'])) - .then(console.timeEnd.bind(console, label)) - .catch(console.error); \ No newline at end of file diff --git a/server.js b/server.js index fe5a9a363..db97336e2 100644 --- a/server.js +++ b/server.js @@ -1,12 +1,29 @@ -import DB from './server/db.js'; -import server from './server/app.js'; +import DB from './server/db.js'; +import createApp from './server/app.js'; import config from './server/config.js'; +import { createServer as createViteServer } from 'vite'; -DB.connect(config).then(()=>{ - // Ensure that we have successfully connected to the database - // before launching server - const PORT = process.env.PORT || config.get('web_port') || 8000; - server.listen(PORT, ()=>{ +const isDev = process.env.NODE_ENV === 'local'; + +async function start() { + let vite; + + if(isDev) { + vite = await createViteServer({ + server : { middlewareMode: true }, + appType : 'custom', + }); + } + + await DB.connect(config).catch((err)=>{ + console.error('Database connection failed:', err); + process.exit(1); + }); + + const app = await createApp(vite); + + const PORT = process.env.PORT || config.get('web_port') || 3000; + app.listen(PORT, ()=>{ const reset = '\x1b[0m'; // Reset to default style const bright = '\x1b[1m'; // Bright (bold) style const cyan = '\x1b[36m'; // Cyan color @@ -14,7 +31,10 @@ DB.connect(config).then(()=>{ console.log(`\n\tserver started at: ${new Date().toLocaleString()}`); console.log(`\tserver on port: ${PORT}`); - console.log(`\t${bright + cyan}Open in browser: ${reset}${underline + bright + cyan}http://localhost:${PORT}${reset}\n\n`); - + console.log( + `\t${bright + cyan}Open in browser: ${reset}${underline + bright + cyan}http://localhost:${PORT}${reset}\n\n`, + ); }); -}); +} + +start(); diff --git a/server/admin.api.js b/server/admin.api.js index a3d7622f1..f55eefdf2 100644 --- a/server/admin.api.js +++ b/server/admin.api.js @@ -4,64 +4,69 @@ import { model as NotificationModel } from './notifications.model.js'; import express from 'express'; import Moment from 'moment'; import zlib from 'zlib'; -import templateFn from '../client/template.js'; +import config from './config.js'; +import path from 'path'; +import fs from 'fs-extra'; + +const nodeEnv = config.get('node_env'); +const isProd = nodeEnv === 'production'; import HomebrewAPI from './homebrew.api.js'; import asyncHandler from 'express-async-handler'; import { splitTextStyleAndMetadata } from '../shared/helpers.js'; -const router = express.Router(); - - process.env.ADMIN_USER = process.env.ADMIN_USER || 'admin'; process.env.ADMIN_PASS = process.env.ADMIN_PASS || 'password3'; -const mw = { - adminOnly : (req, res, next)=>{ - if(!req.get('authorization')){ - return res +export default function createAdminApi(vite) { + const router = express.Router(); + + const mw = { + adminOnly : (req, res, next)=>{ + if(!req.get('authorization')){ + return res .set('WWW-Authenticate', 'Basic realm="Authorization Required"') .status(401) .send('Authorization Required'); - } - const [username, password] = Buffer.from(req.get('authorization').split(' ').pop(), 'base64') + } + const [username, password] = Buffer.from(req.get('authorization').split(' ').pop(), 'base64') .toString('ascii') .split(':'); - if(process.env.ADMIN_USER === username && process.env.ADMIN_PASS === password){ - return next(); + if(process.env.ADMIN_USER === username && process.env.ADMIN_PASS === password){ + return next(); + } + throw { HBErrorCode: '52', code: 401, message: 'Access denied' }; } - throw { HBErrorCode: '52', code: 401, message: 'Access denied' }; - } -}; + }; -const junkBrewPipeline = [ - { $match : { - updatedAt : { $lt: Moment().subtract(30, 'days').toDate() }, - lastViewed : { $lt: Moment().subtract(30, 'days').toDate() } - } }, - { $project: { textBinSize: { $binarySize: '$textBin' } } }, - { $match: { textBinSize: { $lt: 140 } } }, - { $limit: 100 } -]; + const junkBrewPipeline = [ + { $match : { + updatedAt : { $lt: Moment().subtract(30, 'days').toDate() }, + lastViewed : { $lt: Moment().subtract(30, 'days').toDate() } + } }, + { $project: { textBinSize: { $binarySize: '$textBin' } } }, + { $match: { textBinSize: { $lt: 140 } } }, + { $limit: 100 } + ]; -/* Search for brews that aren't compressed (missing the compressed text field) */ -const uncompressedBrewQuery = HomebrewModel.find({ - 'text' : { '$exists': true } -}).lean().limit(10000).select('_id'); + /* Search for brews that aren't compressed (missing the compressed text field) */ + const uncompressedBrewQuery = HomebrewModel.find({ + 'text' : { '$exists': true } + }).lean().limit(10000).select('_id'); -// Search for up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes -router.get('/admin/cleanup', mw.adminOnly, (req, res)=>{ - HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) + // Search for up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes + router.get('/admin/cleanup', mw.adminOnly, (req, res)=>{ + HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) .then((objs)=>res.json({ count: objs.length })) .catch((error)=>{ console.error(error); res.status(500).json({ error: 'Internal Server Error' }); }); -}); + }); -// Delete up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes -router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{ - HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) + // Delete up to 100 brews that have not been viewed or updated in 30 days and are shorter than 140 bytes + router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{ + HomebrewModel.aggregate(junkBrewPipeline).option({ maxTimeMS: 60000 }) .then((docs)=>{ const ids = docs.map((doc)=>doc._id); return HomebrewModel.deleteMany({ _id: { $in: ids } }); @@ -71,18 +76,18 @@ router.post('/admin/cleanup', mw.adminOnly, (req, res)=>{ console.error(error); res.status(500).json({ error: 'Internal Server Error' }); }); -}); + }); -/* Searches for matching edit or share id, also attempts to partial match */ -router.get('/admin/lookup/:id', mw.adminOnly, asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res, next)=>{ - return res.json(req.brew); -}); + /* Searches for matching edit or share id, also attempts to partial match */ + router.get('/admin/lookup/:id', mw.adminOnly, asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res, next)=>{ + return res.json(req.brew); + }); -/* Find 50 brews that aren't compressed yet */ -router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ - const query = uncompressedBrewQuery.clone(); + /* Find 50 brews that aren't compressed yet */ + router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ + const query = uncompressedBrewQuery.clone(); - query.exec() + query.exec() .then((objs)=>{ const ids = objs.map((obj)=>obj._id); res.json({ count: ids.length, ids }); @@ -91,46 +96,46 @@ router.get('/admin/finduncompressed', mw.adminOnly, (req, res)=>{ console.error(err); res.status(500).send(err.message || 'Internal Server Error'); }); -}); - -/* Cleans `` from the "text" field of a brew */ -router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res)=>{ - console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Cleaning script tags from ShareID ${req.params.id}`); - - function cleanText(text){return text.replaceAll(/(<\/?s)cript/gi, '');}; - - const brew = req.brew; - - const properties = ['text', 'description', 'title']; - properties.forEach((property)=>{ - brew[property] = cleanText(brew[property]); }); - splitTextStyleAndMetadata(brew); + /* Cleans `` from the "text" field of a brew */ + router.put('/admin/clean/script/:id', asyncHandler(HomebrewAPI.getBrew('admin', false)), async (req, res)=>{ + console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Cleaning script tags from ShareID ${req.params.id}`); - req.body = brew; + function cleanText(text){return text.replaceAll(/(<\/?s)cript/gi, '');}; - // Remove Account from request to prevent Admin user from being added to brew as an Author - req.account = undefined; + const brew = req.brew; - return await HomebrewAPI.updateBrew(req, res); -}); + const properties = ['text', 'description', 'title']; + properties.forEach((property)=>{ + brew[property] = cleanText(brew[property]); + }); -/* Get list of a user's documents */ -router.get('/admin/user/list/:user', mw.adminOnly, async (req, res)=>{ - const username = req.params.user; - const fields = { _id: 0, text: 0, textBin: 0 }; // Remove unnecessary fields from document lists + splitTextStyleAndMetadata(brew); - console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Get brew list for ${username}`); + req.body = brew; - const brews = await HomebrewModel.getByUser(username, true, fields); + // Remove Account from request to prevent Admin user from being added to brew as an Author + req.account = undefined; - return res.json(brews); -}); + return await HomebrewAPI.updateBrew(req, res); + }); -/* Compresses the "text" field of a brew to binary */ -router.put('/admin/compress/:id', (req, res)=>{ - HomebrewModel.findOne({ _id: req.params.id }) + /* Get list of a user's documents */ + router.get('/admin/user/list/:user', mw.adminOnly, async (req, res)=>{ + const username = req.params.user; + const fields = { _id: 0, text: 0, textBin: 0 }; // Remove unnecessary fields from document lists + + console.log(`[ADMIN: ${req.account?.username || 'Not Logged In'}] Get brew list for ${username}`); + + const brews = await HomebrewModel.getByUser(username, true, fields); + + return res.json(brews); + }); + + /* Compresses the "text" field of a brew to binary */ + router.put('/admin/compress/:id', (req, res)=>{ + HomebrewModel.findOne({ _id: req.params.id }) .then((brew)=>{ if(!brew) return res.status(404).send('Brew not found'); @@ -147,239 +152,252 @@ router.put('/admin/compress/:id', (req, res)=>{ console.error(err); res.status(500).send('Error while saving'); }); -}); + }); -router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ - try { - const totalBrewsCount = await HomebrewModel.countDocuments({}); - const publishedBrewsCount = await HomebrewModel.countDocuments({ published: true }); + router.get('/admin/stats', mw.adminOnly, async (req, res)=>{ + try { + const totalBrewsCount = await HomebrewModel.countDocuments({}); + const publishedBrewsCount = await HomebrewModel.countDocuments({ published: true }); - return res.json({ - totalBrews : totalBrewsCount, - totalPublishedBrews : publishedBrewsCount - }); - } catch (error) { - console.error(error); - return res.status(500).json({ error: 'Internal Server Error' }); - } -}); + return res.json({ + totalBrews : totalBrewsCount, + totalPublishedBrews : publishedBrewsCount + }); + } catch (error) { + console.error(error); + return res.status(500).json({ error: 'Internal Server Error' }); + } + }); -// ####################### LOCKS + // ####################### LOCKS -router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.get('/api/lock/count', mw.adminOnly, asyncHandler(async (req, res)=>{ - const countLocksQuery = { - lock : { $exists: true } - }; - const count = await HomebrewModel.countDocuments(countLocksQuery) + const countLocksQuery = { + lock : { $exists: true } + }; + const count = await HomebrewModel.countDocuments(countLocksQuery) .catch((error)=>{ throw { name: 'Lock Count Error', message: 'Unable to get lock count', status: 500, HBErrorCode: '61', error }; }); - return res.json({ count }); + return res.json({ count }); -})); + })); -router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{ - const countLocksPipeline = [ - { + router.get('/api/locks', mw.adminOnly, asyncHandler(async (req, res)=>{ + const countLocksPipeline = [ + { $match : { 'lock' : { '$exists': 1 } }, - }, - { - $project : { - shareId : 1, - editId : 1, - title : 1, - lock : 1 + }, + { + $project : { + shareId : 1, + editId : 1, + title : 1, + lock : 1 + } } - } - ]; - const lockedDocuments = await HomebrewModel.aggregate(countLocksPipeline) + ]; + const lockedDocuments = await HomebrewModel.aggregate(countLocksPipeline) .catch((error)=>{ throw { name: 'Can Not Get Locked Brews', message: 'Unable to get locked brew collection', status: 500, HBErrorCode: '68', error }; }); - return res.json({ - lockedDocuments - }); + return res.json({ + lockedDocuments + }); -})); + })); -router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.post('/api/lock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ - const lock = req.body; + const lock = req.body; - lock.applied = new Date; + lock.applied = new Date; - const filter = { - shareId : req.params.id - }; + const filter = { + shareId : req.params.id + }; - const brew = await HomebrewModel.findOne(filter); + const brew = await HomebrewModel.findOne(filter); - if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; + if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to lock', shareId: req.params.id, status: 500, HBErrorCode: '63' }; - if(brew.lock && !lock.overwrite) { - throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; - } + if(brew.lock && !lock.overwrite) { + throw { name: 'Already Locked', message: 'Lock already exists on brew', shareId: req.params.id, title: brew.title, status: 500, HBErrorCode: '64' }; + } - lock.overwrite = undefined; + lock.overwrite = undefined; - brew.lock = lock; - brew.markModified('lock'); + brew.lock = lock; + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Lock Error', message: 'Unable to set lock', shareId: req.params.id, status: 500, HBErrorCode: '62', error }; }); - return res.json({ name: 'LOCKED', message: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); + return res.json({ name: 'LOCKED', message: `Lock applied to brew ID ${brew.shareId} - ${brew.title}`, ...lock }); -})); + })); -router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.put('/api/unlock/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ - const filter = { - shareId : req.params.id - }; + const filter = { + shareId : req.params.id + }; - const brew = await HomebrewModel.findOne(filter); + const brew = await HomebrewModel.findOne(filter); - if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to unlock', shareId: req.params.id, status: 500, HBErrorCode: '66' }; + if(!brew) throw { name: 'Brew Not Found', message: 'Cannot find brew to unlock', shareId: req.params.id, status: 500, HBErrorCode: '66' }; - if(!brew.lock) throw { name: 'Not Locked', message: 'Cannot unlock as brew is not locked', shareId: req.params.id, status: 500, HBErrorCode: '67' }; + if(!brew.lock) throw { name: 'Not Locked', message: 'Cannot unlock as brew is not locked', shareId: req.params.id, status: 500, HBErrorCode: '67' }; - brew.lock = undefined; - brew.markModified('lock'); + brew.lock = undefined; + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Cannot Unlock', message: 'Unable to clear lock', shareId: req.params.id, status: 500, HBErrorCode: '65', error }; }); - return res.json({ name: 'Unlocked', message: `Lock removed from brew ID ${req.params.id}` }); -})); + return res.json({ name: 'Unlocked', message: `Lock removed from brew ID ${req.params.id}` }); + })); -router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ - const countReviewsPipeline = [ - { + router.get('/api/lock/reviews', mw.adminOnly, asyncHandler(async (req, res)=>{ + const countReviewsPipeline = [ + { $match : { 'lock.reviewRequested' : { '$exists': 1 } }, - }, - { - $project : { - shareId : 1, - editId : 1, - title : 1, - lock : 1 + }, + { + $project : { + shareId : 1, + editId : 1, + title : 1, + lock : 1 + } } - } - ]; - const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) + ]; + const reviewDocuments = await HomebrewModel.aggregate(countReviewsPipeline) .catch((error)=>{ throw { name: 'Can Not Get Reviews', message: 'Unable to get review collection', status: 500, HBErrorCode: '68', error }; }); - return res.json({ - reviewDocuments - }); + return res.json({ + reviewDocuments + }); -})); + })); -router.put('/api/lock/review/request/:id', asyncHandler(async (req, res)=>{ + router.put('/api/lock/review/request/:id', asyncHandler(async (req, res)=>{ // === This route is NOT Admin only === // Any user can request a review of their document - const filter = { - shareId : req.params.id, - lock : { $exists: 1 } - }; + const filter = { + shareId : req.params.id, + lock : { $exists: 1 } + }; - const brew = await HomebrewModel.findOne(filter); - if(!brew) { throw { name: 'Brew Not Found', message: `Cannot find a locked brew with ID ${req.params.id}`, code: 500, HBErrorCode: '70' }; }; + const brew = await HomebrewModel.findOne(filter); + if(!brew) { throw { name: 'Brew Not Found', message: `Cannot find a locked brew with ID ${req.params.id}`, code: 500, HBErrorCode: '70' }; }; - if(brew.lock.reviewRequested){ - throw { name: 'Review Already Requested', message: `Review already requested for brew ${brew.shareId} - ${brew.title}`, code: 500, HBErrorCode: '71' }; - }; + if(brew.lock.reviewRequested){ + throw { name: 'Review Already Requested', message: `Review already requested for brew ${brew.shareId} - ${brew.title}`, code: 500, HBErrorCode: '71' }; + }; - brew.lock.reviewRequested = new Date(); - brew.markModified('lock'); + brew.lock.reviewRequested = new Date(); + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Can Not Set Review Request', message: `Unable to set request for review on brew ID ${req.params.id}`, code: 500, HBErrorCode: '69', error }; }); - return res.json({ name: 'Review Requested', message: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); + return res.json({ name: 'Review Requested', message: `Review requested on brew ID ${brew.shareId} - ${brew.title}` }); -})); + })); -router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ + router.put('/api/lock/review/remove/:id', mw.adminOnly, asyncHandler(async (req, res)=>{ - const filter = { - shareId : req.params.id, - 'lock.reviewRequested' : { $exists: 1 } - }; + const filter = { + shareId : req.params.id, + 'lock.reviewRequested' : { $exists: 1 } + }; - const brew = await HomebrewModel.findOne(filter); - if(!brew) { throw { name: 'Can Not Clear Review Request', message: `Brew ID ${req.params.id} does not have a review pending!`, HBErrorCode: '73' }; }; + const brew = await HomebrewModel.findOne(filter); + if(!brew) { throw { name: 'Can Not Clear Review Request', message: `Brew ID ${req.params.id} does not have a review pending!`, HBErrorCode: '73' }; }; - brew.lock.reviewRequested = undefined; - brew.markModified('lock'); + brew.lock.reviewRequested = undefined; + brew.markModified('lock'); - await brew.save() + await brew.save() .catch((error)=>{ throw { name: 'Can Not Clear Review Request', message: `Unable to remove request for review on brew ID ${req.params.id}`, HBErrorCode: '72', error }; }); - return res.json({ name: 'Review Request Cleared', message: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); + return res.json({ name: 'Review Request Cleared', message: `Review request removed for brew ID ${brew.shareId} - ${brew.title}` }); -})); + })); -// ####################### NOTIFICATIONS + // ####################### NOTIFICATIONS -router.get('/admin/notification/all', async (req, res, next)=>{ - try { - const notifications = await NotificationModel.getAll(); - return res.json(notifications); + router.get('/admin/notification/all', async (req, res, next)=>{ + try { + const notifications = await NotificationModel.getAll(); + return res.json(notifications); - } catch (error) { - console.log('Error getting all notifications: ', error.message); - return res.status(500).json({ message: error.message }); - } -}); - -router.post('/admin/notification/add', mw.adminOnly, async (req, res, next)=>{ - try { - const notification = await NotificationModel.addNotification(req.body); - return res.status(201).json(notification); - } catch (error) { - console.log('Error adding notification: ', error.message); - return res.status(500).json({ message: error.message }); - } -}); - -router.delete('/admin/notification/delete/:id', mw.adminOnly, async (req, res, next)=>{ - try { - const notification = await NotificationModel.deleteNotification(req.params.id); - return res.json(notification); - } catch (error) { - console.error('Error deleting notification: { key: ', req.params.id, ' error: ', error.message, ' }'); - return res.status(500).json({ message: error.message }); - } -}); - -router.get('/admin', mw.adminOnly, (req, res)=>{ - templateFn('admin', { - url : req.originalUrl - }) - .then((page)=>res.send(page)) - .catch((err)=>{ - console.log(err); - res.sendStatus(500); + } catch (error) { + console.log('Error getting all notifications: ', error.message); + return res.status(500).json({ message: error.message }); + } }); -}); -export default router; + router.post('/admin/notification/add', mw.adminOnly, async (req, res, next)=>{ + try { + const notification = await NotificationModel.addNotification(req.body); + return res.status(201).json(notification); + } catch (error) { + console.log('Error adding notification: ', error.message); + return res.status(500).json({ message: error.message }); + } + }); + + router.delete('/admin/notification/delete/:id', mw.adminOnly, async (req, res, next)=>{ + try { + const notification = await NotificationModel.deleteNotification(req.params.id); + return res.json(notification); + } catch (error) { + console.error('Error deleting notification: { key: ', req.params.id, ' error: ', error.message, ' }'); + return res.status(500).json({ message: error.message }); + } + }); + + router.get('/admin', mw.adminOnly, asyncHandler(async (req, res)=>{ + const props = { + url : req.originalUrl + }; + + const htmlPath = isProd + ? path.resolve('build', 'index.html') + : path.resolve('index.html'); + + let html = fs.readFileSync(htmlPath, 'utf-8'); + + if(!isProd && vite?.transformIndexHtml) { + html = await vite.transformIndexHtml(req.originalUrl, html); + } + + res.send(html.replace( + '', + `\n` + )); + })); + + + return router; +} + diff --git a/server/admin.api.spec.js b/server/admin.api.spec.js index cb25dd67d..ce2a06d0d 100644 --- a/server/admin.api.spec.js +++ b/server/admin.api.spec.js @@ -1,42 +1,45 @@ /*eslint max-lines: ["warn", {"max": 1000, "skipBlankLines": true, "skipComments": true}]*/ import mongoose from 'mongoose'; import supertest from 'supertest'; -import HBApp from './app.js'; +import createApp from './app.js'; import { model as NotificationModel } from './notifications.model.js'; import { model as HomebrewModel } from './homebrew.model.js'; - -// Mimic https responses to avoid being redirected all the time -const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https'); - +let app; +let request; let dbState; +beforeAll(async ()=>{ + app = await createApp(); + request = supertest.agent(app).set('X-Forwarded-Proto', 'https'); +}); + describe('Tests for admin api', ()=>{ beforeEach(()=>{ - // Mock DB ready (for dbCheck middleware) dbState = mongoose.connection.readyState; mongoose.connection.readyState = 1; }); afterEach(()=>{ - // Restore DB ready state mongoose.connection.readyState = dbState; - jest.resetAllMocks(); }); + afterAll(async ()=>{ + await mongoose.connection.close(); + }); + describe('Notifications', ()=>{ it('should return list of all notifications', async ()=>{ const testNotifications = ['a', 'b']; - jest.spyOn(NotificationModel, 'find') - .mockImplementationOnce(()=>{ + jest.spyOn(NotificationModel, 'find').mockImplementationOnce(()=>{ return { exec: jest.fn().mockResolvedValue(testNotifications) }; }); - const response = await app - .get('/admin/notification/all') - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + const response = await request + .get('/admin/notification/all') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual(testNotifications); @@ -56,18 +59,17 @@ describe('Tests for admin api', ()=>{ _id : expect.any(String), createdAt : expect.any(String), startAt : inputNotification.startAt, - stopAt : inputNotification.stopAt, + stopAt : inputNotification.stopAt }; - jest.spyOn(NotificationModel.prototype, 'save') - .mockImplementationOnce(function() { - return Promise.resolve(this); - }); + jest.spyOn(NotificationModel.prototype, 'save').mockImplementationOnce(function () { + return Promise.resolve(this); + }); - const response = await app - .post('/admin/notification/add') - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .send(inputNotification); + const response = await request + .post('/admin/notification/add') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(inputNotification); expect(response.status).toBe(201); expect(response.body).toEqual(savedNotification); @@ -81,16 +83,14 @@ describe('Tests for admin api', ()=>{ stopAt : new Date().toISOString() }; - //Change 'save' function to just return itself instead of actually interacting with the database - jest.spyOn(NotificationModel.prototype, 'save') - .mockImplementationOnce(function() { - return Promise.resolve(this); - }); + jest.spyOn(NotificationModel.prototype, 'save').mockImplementationOnce(function () { + return Promise.resolve(this); + }); - const response = await app - .post('/admin/notification/add') - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .send(inputNotification); + const response = await request + .post('/admin/notification/add') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(inputNotification); expect(response.status).toBe(500); expect(response.body).toEqual({ message: 'Dismiss key is required!' }); @@ -99,15 +99,15 @@ describe('Tests for admin api', ()=>{ it('should delete a notification based on its dismiss key', async ()=>{ const dismissKey = 'testKey'; - jest.spyOn(NotificationModel, 'findOneAndDelete') - .mockImplementationOnce((key)=>{ - return { exec: jest.fn().mockResolvedValue(key) }; - }); - const response = await app - .delete(`/admin/notification/delete/${dismissKey}`) - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + jest.spyOn(NotificationModel, 'findOneAndDelete').mockImplementationOnce((key)=>{ + return { exec: jest.fn().mockResolvedValue(key) }; + }); - expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' }); + const response = await request + .delete(`/admin/notification/delete/${dismissKey}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + + expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ dismissKey: 'testKey' }); expect(response.status).toBe(200); expect(response.body).toEqual({ dismissKey: 'testKey' }); }); @@ -115,15 +115,15 @@ describe('Tests for admin api', ()=>{ it('should handle error deleting a notification that doesnt exist', async ()=>{ const dismissKey = 'testKey'; - jest.spyOn(NotificationModel, 'findOneAndDelete') - .mockImplementationOnce(()=>{ - return { exec: jest.fn().mockResolvedValue() }; - }); - const response = await app - .delete(`/admin/notification/delete/${dismissKey}`) - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + jest.spyOn(NotificationModel, 'findOneAndDelete').mockImplementationOnce(()=>{ + return { exec: jest.fn().mockResolvedValue() }; + }); - expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ 'dismissKey': 'testKey' }); + const response = await request + .delete(`/admin/notification/delete/${dismissKey}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); + + expect(NotificationModel.findOneAndDelete).toHaveBeenCalledWith({ dismissKey: 'testKey' }); expect(response.status).toBe(500); expect(response.body).toEqual({ message: 'Notification not found' }); }); @@ -132,30 +132,24 @@ describe('Tests for admin api', ()=>{ describe('Locks', ()=>{ describe('Count', ()=>{ it('Count of all locked documents', async ()=>{ - const testNumber = 16777216; // 8^8, because why not + const testNumber = 16777216; - jest.spyOn(HomebrewModel, 'countDocuments') - .mockImplementationOnce(()=>{ - return Promise.resolve(testNumber); - }); + jest.spyOn(HomebrewModel, 'countDocuments').mockImplementationOnce(()=>Promise.resolve(testNumber)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/count'); + const response = await request + .get('/api/lock/count') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ count: testNumber }); }); it('Handle error while fetching count of locked documents', async ()=>{ - jest.spyOn(HomebrewModel, 'countDocuments') - .mockImplementationOnce(()=>{ - return Promise.reject(); - }); + jest.spyOn(HomebrewModel, 'countDocuments').mockImplementationOnce(()=>Promise.reject()); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/count'); + const response = await request + .get('/api/lock/count') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -163,7 +157,7 @@ describe('Tests for admin api', ()=>{ message : 'Unable to get lock count', name : 'Lock Count Error', originalUrl : '/api/lock/count', - status : 500, + status : 500 }); }); }); @@ -172,28 +166,22 @@ describe('Tests for admin api', ()=>{ it('Get list of all locked documents', async ()=>{ const testLocks = ['a', 'b']; - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.resolve(testLocks); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.resolve(testLocks)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/locks'); + const response = await request + .get('/api/locks') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ lockedDocuments: testLocks }); }); it('Handle error while fetching list of all locked documents', async ()=>{ - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.reject(); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.reject()); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/locks'); + const response = await request + .get('/api/locks') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -208,28 +196,22 @@ describe('Tests for admin api', ()=>{ it('Get list of all locked documents with pending review requests', async ()=>{ const testLocks = ['a', 'b']; - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.resolve(testLocks); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.resolve(testLocks)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/reviews'); + const response = await request + .get('/api/lock/reviews') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ reviewDocuments: testLocks }); }); it('Handle error while fetching list of all locked documents with pending review requests', async ()=>{ - jest.spyOn(HomebrewModel, 'aggregate') - .mockImplementationOnce(()=>{ - return Promise.reject(); - }); + jest.spyOn(HomebrewModel, 'aggregate').mockImplementationOnce(()=>Promise.reject()); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .get('/api/lock/reviews'); + const response = await request + .get('/api/lock/reviews') + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -247,8 +229,8 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); } + markModified : ()=>true, + save : ()=>Promise.resolve() }; const testLock = { @@ -257,15 +239,12 @@ describe('Tests for admin api', ()=>{ shareMessage : 'share' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(200); expect(response.body).toMatchObject({ @@ -289,24 +268,21 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : { code : 1, editMessage : 'oldEdit', - shareMessage : 'oldShare', + shareMessage : 'oldShare' } }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(200); expect(response.body).toMatchObject({ @@ -329,24 +305,21 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : { code : 1, editMessage : 'oldEdit', - shareMessage : 'oldShare', + shareMessage : 'oldShare' } }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -364,8 +337,8 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); } + markModified : ()=>true, + save : ()=>Promise.reject() }; const testLock = { @@ -374,15 +347,12 @@ describe('Tests for admin api', ()=>{ shareMessage : 'share' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .post(`/api/lock/${testBrew.shareId}`) - .send(testLock); + const response = await request + .post(`/api/lock/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) + .send(testLock); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -408,19 +378,17 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/unlock/${testBrew.shareId}`); + const response = await request.put(`/api/unlock/${testBrew.shareId}`).set( + 'Authorization', + `Basic ${Buffer.from('admin:password3').toString('base64')}` + ); expect(response.status).toBe(200); expect(response.body).toEqual({ @@ -433,18 +401,16 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve() }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/unlock/${testBrew.shareId}`); + const response = await request.put(`/api/unlock/${testBrew.shareId}`).set( + 'Authorization', + `Basic ${Buffer.from('admin:password3').toString('base64')}` + ); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -453,7 +419,7 @@ describe('Tests for admin api', ()=>{ name : 'Not Locked', originalUrl : `/api/unlock/${testBrew.shareId}`, shareId : testBrew.shareId, - status : 500, + status : 500 }); }); @@ -468,19 +434,17 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); }, + markModified : ()=>true, + save : ()=>Promise.reject(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/unlock/${testBrew.shareId}`); + const response = await request.put(`/api/unlock/${testBrew.shareId}`).set( + 'Authorization', + `Basic ${Buffer.from('admin:password3').toString('base64')}` + ); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -506,40 +470,28 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`); + const response = await request.put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(200); expect(response.body).toEqual({ message : `Review requested on brew ID ${testBrew.shareId} - ${testBrew.title}`, - name : 'Review Requested', + name : 'Review Requested' }); }); it('Error when cannot find a locked brew', async ()=>{ - const testBrew = { - shareId : 'shareId' - }; + const testBrew = { shareId: 'shareId' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(false); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(false)); - - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`) - .catch((err)=>{return err;}); + const response = await request.put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -569,25 +521,20 @@ describe('Tests for admin api', ()=>{ }; jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(false); - }); + .mockImplementationOnce(()=>Promise.resolve(testBrew)); - - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`) - .catch((err)=>{return err;}); + const response = await request + .put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(500); expect(response.body).toEqual({ - HBErrorCode : '70', + HBErrorCode : '71', code : 500, - message : `Cannot find a locked brew with ID ${testBrew.shareId}`, - name : 'Brew Not Found', + message : `Review already requested for brew ${testBrew.shareId} - ${testBrew.title}`, + name : 'Review Already Requested', originalUrl : `/api/lock/review/request/${testBrew.shareId}` }); }); - it('Handle error while adding review request to a locked brew', async ()=>{ const testLock = { applied : 'YES', @@ -599,18 +546,14 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); }, + markModified : ()=>true, + save : ()=>Promise.reject(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .put(`/api/lock/review/request/${testBrew.shareId}`); + const response = await request.put(`/api/lock/review/request/${testBrew.shareId}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -634,19 +577,16 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.resolve(); }, + markModified : ()=>true, + save : ()=>Promise.resolve(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/lock/review/remove/${testBrew.shareId}`); + const response = await request + .put(`/api/lock/review/remove/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(200); expect(response.body).toEqual({ @@ -656,18 +596,13 @@ describe('Tests for admin api', ()=>{ }); it('Error when clearing review request from a brew with no review request', async ()=>{ - const testBrew = { - shareId : 'shareId', - }; + const testBrew = { shareId: 'shareId' }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(false); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(false)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/lock/review/remove/${testBrew.shareId}`); + const response = await request + .put(`/api/lock/review/remove/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ @@ -690,19 +625,16 @@ describe('Tests for admin api', ()=>{ const testBrew = { shareId : 'shareId', title : 'title', - markModified : ()=>{ return true; }, - save : ()=>{ return Promise.reject(); }, + markModified : ()=>true, + save : ()=>Promise.reject(), lock : testLock }; - jest.spyOn(HomebrewModel, 'findOne') - .mockImplementationOnce(()=>{ - return Promise.resolve(testBrew); - }); + jest.spyOn(HomebrewModel, 'findOne').mockImplementationOnce(()=>Promise.resolve(testBrew)); - const response = await app - .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`) - .put(`/api/lock/review/remove/${testBrew.shareId}`); + const response = await request + .put(`/api/lock/review/remove/${testBrew.shareId}`) + .set('Authorization', `Basic ${Buffer.from('admin:password3').toString('base64')}`); expect(response.status).toBe(500); expect(response.body).toEqual({ diff --git a/server/app.js b/server/app.js index 3ecadcf0e..bee173b7e 100644 --- a/server/app.js +++ b/server/app.js @@ -12,10 +12,9 @@ import _ from 'lodash'; import jwt from 'jwt-simple'; import express from 'express'; import config from './config.js'; +import path from 'path'; import fs from 'fs-extra'; -const app = express(); - import api from './homebrew.api.js'; const { homebrewApi, getBrew, getUsersBrewThemes, getCSS } = api; import adminApi from './admin.api.js'; @@ -24,8 +23,7 @@ import GoogleActions from './googleActions.js'; import serveCompressedStaticAssets from './static-assets.mv.js'; import sanitizeFilename from 'sanitize-filename'; import asyncHandler from 'express-async-handler'; -import templateFn from '../client/template.js'; -import { model as HomebrewModel } from './homebrew.model.js'; +import { model as HomebrewModel } from './homebrew.model.js'; import { DEFAULT_BREW } from './brewDefaults.js'; import { splitTextStyleAndMetadata } from '../shared/helpers.js'; @@ -37,612 +35,642 @@ import cookieParser from 'cookie-parser'; import forceSSL from './forcessl.mw.js'; import dbCheck from './middleware/dbCheck.js'; - -const sanitizeBrew = (brew, accessType)=>{ - brew._id = undefined; - brew.__v = undefined; - if(accessType !== 'edit' && accessType !== 'shareAuthor') { - brew.editId = undefined; - } - return brew; -}; - -const encodeRFC3986ValueChars = (str)=>{ - return ( - encodeURIComponent(str) - .replace(/[!'()*]/g, (char)=>{`%${char.charCodeAt(0).toString(16).toUpperCase()}`;}) - ); -}; - - -app.set('trust proxy', 1 /* number of proxies between user and server */); - -app.use('/', serveCompressedStaticAssets(`build`)); -app.use(contentNegotiation); -app.use(bodyParser.json({ limit: '25mb' })); -app.use(cookieParser()); -app.use(forceSSL); - import cors from 'cors'; -const nodeEnv = config.get('node_env'); -const isLocalEnvironment = config.get('local_environments').includes(nodeEnv); +export default async function createApp(vite) { + const app = express(); -const corsOptions = { - origin : (origin, callback)=>{ + const nodeEnv = config.get('node_env'); + const isProd = nodeEnv === 'production'; + const isLocalEnvironment = config.get('local_environments').includes(nodeEnv); - const allowedOrigins = [ - 'https://homebrewery.naturalcrit.com', - 'https://www.naturalcrit.com', - 'https://naturalcrit-stage.herokuapp.com', - 'https://homebrewery-stage.herokuapp.com', - ]; - - const localNetworkRegex = /^http:\/\/(localhost|127\.0\.0\.1|10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|172\.(1[6-9]|2\d|3[0-1])\.\d+\.\d+):\d+$/; - - const herokuRegex = /^https:\/\/(?:homebrewery-pr-\d+\.herokuapp\.com|naturalcrit-pr-\d+\.herokuapp\.com)$/; // Matches any Heroku app - - if(!origin || allowedOrigins.includes(origin) || herokuRegex.test(origin) || (isLocalEnvironment && localNetworkRegex.test(origin))) { - callback(null, true); - } else { - console.log(origin, 'not allowed'); - callback(new Error('Not allowed by CORS, if you think this is an error, please contact us')); + const sanitizeBrew = (brew, accessType)=>{ + brew._id = undefined; + brew.__v = undefined; + if(accessType !== 'edit' && accessType !== 'shareAuthor') { + brew.editId = undefined; } - }, - methods : ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], - credentials : true, -}; + return brew; + }; -app.use(cors(corsOptions)); + app.set('trust proxy', 1 /* number of proxies between user and server */); -//Account Middleware -app.use((req, res, next)=>{ - if(req.cookies && req.cookies.nc_session){ - try { - req.account = jwt.decode(req.cookies.nc_session, config.get('secret')); + if(vite) { + app.use(vite.middlewares); + } + + app.use('/', serveCompressedStaticAssets('build')); + app.use(contentNegotiation); + app.use(bodyParser.json({ limit: '25mb' })); + app.use(cookieParser()); + app.use(forceSSL); + + + const corsOptions = { + origin : (origin, callback)=>{ + + const allowedOrigins = [ + 'https://homebrewery.naturalcrit.com', + 'https://www.naturalcrit.com', + 'https://naturalcrit-stage.herokuapp.com', + 'https://homebrewery-stage.herokuapp.com', + ]; + + const localNetworkRegex = /^http:\/\/(localhost|127\.0\.0\.1|10\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|172\.(1[6-9]|2\d|3[0-1])\.\d+\.\d+):\d+$/; + + const herokuRegex = /^https:\/\/(?:homebrewery-pr-\d+\.herokuapp\.com|naturalcrit-pr-\d+\.herokuapp\.com)$/; // Matches any Heroku app + + console.log(isLocalEnvironment); + console.log(localNetworkRegex.test(origin)); + console.log(origin == 'null'); + + if(!origin | origin == 'null' || allowedOrigins.includes(origin) || herokuRegex.test(origin) || (isLocalEnvironment && localNetworkRegex.test(origin))) { + callback(null, true); + } else { + console.log(origin, 'not allowed'); + callback(new Error('Not allowed by CORS, if you think this is an error, please contact us')); + } + }, + methods : ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], + credentials : true, + }; + + app.use(cors(corsOptions)); + + //Account Middleware + app.use((req, res, next)=>{ + if(req.cookies && req.cookies.nc_session){ + try { + req.account = jwt.decode(req.cookies.nc_session, config.get('secret')); //console.log("Just loaded up JWT from cookie:"); //console.log(req.account); - } catch (e){ - console.log(e); + } catch (e){ + console.log(e); + } } - } - req.config = { - google_client_id : config.get('google_client_id'), - google_client_secret : config.get('google_client_secret') - }; - return next(); -}); - -app.use(homebrewApi); -app.use(adminApi); -app.use(vaultApi); - -const welcomeText = fs.readFileSync('client/homebrew/pages/homePage/welcome_msg.md', 'utf8'); -const welcomeTextLegacy = fs.readFileSync('client/homebrew/pages/homePage/welcome_msg_legacy.md', 'utf8'); -const migrateText = fs.readFileSync('client/homebrew/pages/homePage/migrate.md', 'utf8'); -const changelogText = fs.readFileSync('changelog.md', 'utf8'); -const faqText = fs.readFileSync('faq.md', 'utf8'); - -String.prototype.replaceAll = function(s, r){return this.split(s).join(r);}; - -const defaultMetaTags = { - site_name : 'The Homebrewery - Make your Homebrew content look legit!', - title : 'The Homebrewery', - description : 'A NaturalCrit Tool for creating authentic Homebrews using Markdown.', - image : `${config.get('publicUrl')}/thumbnail.png`, - type : 'website' -}; - -//Robots.txt -app.get('/robots.txt', (req, res)=>{ - return res.sendFile(`robots.txt`, { root: process.cwd() }); -}); - -//Home page -app.get('/', (req, res, next)=>{ - req.brew = { - text : welcomeText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'Homepage', - description : 'Homepage' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Home page Legacy -app.get('/legacy', (req, res, next)=>{ - req.brew = { - text : welcomeTextLegacy, - renderer : 'legacy', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'Homepage (Legacy)', - description : 'Homepage' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Legacy/Other Document -> v3 Migration Guide -app.get('/migrate', (req, res, next)=>{ - req.brew = { - text : migrateText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'v3 Migration Guide', - description : 'A brief guide to converting Legacy documents to the v3 renderer.' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Changelog page -app.get('/changelog', async (req, res, next)=>{ - req.brew = { - title : 'Changelog', - text : changelogText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'Changelog', - description : 'Development changelog.' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//FAQ page -app.get('/faq', async (req, res, next)=>{ - req.brew = { - title : 'FAQ', - text : faqText, - renderer : 'V3', - theme : '5ePHB' - }, - - req.ogMeta = { ...defaultMetaTags, - title : 'FAQ', - description : 'Frequently Asked Questions' - }; - - splitTextStyleAndMetadata(req.brew); - return next(); -}); - -//Source page -app.get('/source/:id', asyncHandler(getBrew('share')), (req, res)=>{ - const { brew } = req; - - const replaceStrings = { '&': '&', '<': '<', '>': '>' }; - let text = brew.text; - for (const replaceStr in replaceStrings) { - text = text.replaceAll(replaceStr, replaceStrings[replaceStr]); - } - text = `
${text}
`; - res.status(200).send(text); -}); - - -//Download brew source page -app.get('/download/:id', asyncHandler(getBrew('share')), (req, res)=>{ - const { brew } = req; - sanitizeBrew(brew, 'share'); - const prefix = 'HB - '; - - let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', ''); - if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; }; - res.set({ - 'Cache-Control' : 'no-cache', - 'Content-Type' : 'text/plain', - 'Content-Disposition' : `attachment; filename*=UTF-8''${encodeRFC3986ValueChars(fileName)}.txt` + req.config = { + google_client_id : config.get('google_client_id'), + google_client_secret : config.get('google_client_secret') + }; + return next(); }); - res.status(200).send(brew.text); -}); -//Serve brew metadata -app.get('/metadata/:id', asyncHandler(getBrew('share')), (req, res)=>{ - const { brew } = req; - sanitizeBrew(brew, 'share'); + app.use(homebrewApi); + app.use(adminApi(vite)); + app.use(vaultApi); - const fields = ['title', 'pageCount', 'description', 'authors', 'lang', + const welcomeText = fs.readFileSync('./client/homebrew/pages/homePage/welcome_msg.md', 'utf8'); + const welcomeTextLegacy = fs.readFileSync('./client/homebrew/pages/homePage/welcome_msg_legacy.md', 'utf8'); + const migrateText = fs.readFileSync('./client/homebrew/pages/homePage/migrate.md', 'utf8'); + const changelogText = fs.readFileSync('changelog.md', 'utf8'); + const faqText = fs.readFileSync('faq.md', 'utf8'); + + String.prototype.replaceAll = function(s, r){return this.split(s).join(r);}; + + const defaultMetaTags = { + site_name : 'The Homebrewery - Make your Homebrew content look legit!', + title : 'The Homebrewery', + description : 'A NaturalCrit Tool for creating authentic Homebrews using Markdown.', + image : `${config.get('publicUrl')}/thumbnail.png`, + type : 'website' + }; + + //Robots.txt + app.get('/robots.txt', (req, res)=>{ + return res.sendFile(`robots.txt`, { root: process.cwd() }); + }); + + //Home page + app.get('/', (req, res, next)=>{ + req.brew = { + text : welcomeText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'Homepage', + description : 'Homepage' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Home page Legacy + app.get('/legacy', (req, res, next)=>{ + req.brew = { + text : welcomeTextLegacy, + renderer : 'legacy', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'Homepage (Legacy)', + description : 'Homepage' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Legacy/Other Document -> v3 Migration Guide + app.get('/migrate', (req, res, next)=>{ + req.brew = { + text : migrateText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'v3 Migration Guide', + description : 'A brief guide to converting Legacy documents to the v3 renderer.' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Changelog page + app.get('/changelog', async (req, res, next)=>{ + req.brew = { + title : 'Changelog', + text : changelogText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'Changelog', + description : 'Development changelog.' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //FAQ page + app.get('/faq', async (req, res, next)=>{ + req.brew = { + title : 'FAQ', + text : faqText, + renderer : 'V3', + theme : '5ePHB' + }, + + req.ogMeta = { ...defaultMetaTags, + title : 'FAQ', + description : 'Frequently Asked Questions' + }; + + splitTextStyleAndMetadata(req.brew); + return next(); + }); + + //Source page + app.get('/source/:id', asyncHandler(getBrew('share')), (req, res)=>{ + const { brew } = req; + + const replaceStrings = { '&': '&', '<': '<', '>': '>' }; + let text = brew.text; + for (const replaceStr in replaceStrings) { + text = text.replaceAll(replaceStr, replaceStrings[replaceStr]); + } + text = `
${text}
`; + res.status(200).send(text); + }); + + //Download brew source page + app.get('/download/:id', asyncHandler(getBrew('share')), (req, res)=>{ + const { brew } = req; + sanitizeBrew(brew, 'share'); + const prefix = 'HB - '; + + const encodeRFC3986ValueChars = (str)=>{ + return ( + encodeURIComponent(str) + .replace(/[!'()*]/g, (char)=>{`%${char.charCodeAt(0).toString(16).toUpperCase()}`;}) + ); + }; + + let fileName = sanitizeFilename(`${prefix}${brew.title}`).replaceAll(' ', ''); + if(!fileName || !fileName.length) { fileName = `${prefix}-Untitled-Brew`; }; + res.set({ + 'Cache-Control' : 'no-cache', + 'Content-Type' : 'text/plain', + 'Content-Disposition' : `attachment; filename*=UTF-8''${encodeRFC3986ValueChars(fileName)}.txt` + }); + res.status(200).send(brew.text); + }); + + //Serve brew metadata + app.get('/metadata/:id', asyncHandler(getBrew('share')), (req, res)=>{ + const { brew } = req; + sanitizeBrew(brew, 'share'); + + const fields = ['title', 'pageCount', 'description', 'authors', 'lang', 'published', 'views', 'shareId', 'createdAt', 'updatedAt', 'lastViewed', 'thumbnail', 'tags' - ]; + ]; - const metadata = fields.reduce((acc, field)=>{ + const metadata = fields.reduce((acc, field)=>{ if(brew[field] !== undefined) acc[field] = brew[field]; return acc; - }, {}); - res.status(200).json(metadata); -}); + }, {}); + res.status(200).json(metadata); + }); -//Serve brew styling -app.get('/css/:id', asyncHandler(getBrew('share')), (req, res)=>{getCSS(req, res);}); + //Serve brew styling + app.get('/css/:id', asyncHandler(getBrew('share')), (req, res)=>{getCSS(req, res);}); -//User Page -app.get('/user/:username', dbCheck, async (req, res, next)=>{ - const ownAccount = req.account && (req.account.username == req.params.username); + //User Page + app.get('/user/:username', dbCheck, async (req, res, next)=>{ + const ownAccount = req.account && (req.account.username == req.params.username); - req.ogMeta = { ...defaultMetaTags, - title : `${req.params.username}'s Collection`, - description : 'View my collection of homebrew on the Homebrewery.' + req.ogMeta = { ...defaultMetaTags, + title : `${req.params.username}'s Collection`, + description : 'View my collection of homebrew on the Homebrewery.' // type : could be 'profile'? - }; + }; - const fields = [ - 'googleId', - 'title', - 'pageCount', - 'description', - 'authors', - 'lang', - 'published', - 'views', - 'shareId', - 'editId', - 'createdAt', - 'updatedAt', - 'lastViewed', - 'thumbnail', - 'tags' - ]; + const fields = [ + 'googleId', + 'title', + 'pageCount', + 'description', + 'authors', + 'lang', + 'published', + 'views', + 'shareId', + 'editId', + 'createdAt', + 'updatedAt', + 'lastViewed', + 'thumbnail', + 'tags' + ]; - let brews = await HomebrewModel.getByUser(req.params.username, ownAccount, fields) + let brews = await HomebrewModel.getByUser(req.params.username, ownAccount, fields) .catch((err)=>{ console.log(err); }); - brews.forEach((brew)=>brew.stubbed = true); //All brews from MongoDB are "stubbed" + brews.forEach((brew)=>brew.stubbed = true); //All brews from MongoDB are "stubbed" - if(ownAccount && req?.account?.googleId){ - const auth = await GoogleActions.authCheck(req.account, res); - let googleBrews = await GoogleActions.listGoogleBrews(auth) + if(ownAccount && req?.account?.googleId){ + const auth = await GoogleActions.authCheck(req.account, res); + let googleBrews = await GoogleActions.listGoogleBrews(auth) .catch((err)=>{ console.error(err); }); - // If stub matches file from Google, use Google metadata over stub metadata - if(googleBrews && googleBrews.length > 0) { - for (const brew of brews.filter((brew)=>brew.googleId)) { - const match = googleBrews.findIndex((b)=>b.editId === brew.editId); - if(match !== -1) { - brew.googleId = googleBrews[match].googleId; - brew.pageCount = googleBrews[match].pageCount; - brew.renderer = googleBrews[match].renderer; - brew.version = googleBrews[match].version; - brew.webViewLink = googleBrews[match].webViewLink; - googleBrews.splice(match, 1); + // If stub matches file from Google, use Google metadata over stub metadata + if(googleBrews && googleBrews.length > 0) { + for (const brew of brews.filter((brew)=>brew.googleId)) { + const match = googleBrews.findIndex((b)=>b.editId === brew.editId); + if(match !== -1) { + brew.googleId = googleBrews[match].googleId; + brew.pageCount = googleBrews[match].pageCount; + brew.renderer = googleBrews[match].renderer; + brew.version = googleBrews[match].version; + brew.webViewLink = googleBrews[match].webViewLink; + googleBrews.splice(match, 1); + } } + + //Remaining unstubbed google brews display current user as author + googleBrews = googleBrews.map((brew)=>({ ...brew, authors: [req.account.username] })); + brews = _.concat(brews, googleBrews); } - - //Remaining unstubbed google brews display current user as author - googleBrews = googleBrews.map((brew)=>({ ...brew, authors: [req.account.username] })); - brews = _.concat(brews, googleBrews); } - } - req.brews = _.map(brews, (brew)=>{ + req.brews = _.map(brews, (brew)=>{ // Clean up brew data - brew.title = brew.title?.trim(); - brew.description = brew.description?.trim(); - return sanitizeBrew(brew, ownAccount ? 'edit' : 'share'); + brew.title = brew.title?.trim(); + brew.description = brew.description?.trim(); + return sanitizeBrew(brew, ownAccount ? 'edit' : 'share'); + }); + + return next(); }); - return next(); -}); + //Change author name on brews + app.put('/api/user/rename', dbCheck, async (req, res)=>{ + const { username, newUsername } = req.body; + const ownAccount = req.account && (req.account.username == newUsername); -//Change author name on brews -app.put('/api/user/rename', dbCheck, async (req, res)=>{ - const { username, newUsername } = req.body; - const ownAccount = req.account && (req.account.username == newUsername); + if(!username || !newUsername) + return res.status(400).json({ error: 'Username and newUsername are required.' }); + if(!ownAccount) + return res.status(403).json({ error: 'Must be logged in to change your username' }); + try { + const brews = await HomebrewModel.getByUser(username, true, ['authors']); + const renamePromises = brews.map(async (brew)=>{ + const updatedAuthors = brew.authors.map((author)=>author === username ? newUsername : author + ); + return HomebrewModel.updateOne( + { _id: brew._id }, + { $set: { authors: updatedAuthors } } + ); + }); + await Promise.all(renamePromises); - if(!username || !newUsername) - return res.status(400).json({ error: 'Username and newUsername are required.' }); - if(!ownAccount) - return res.status(403).json({ error: 'Must be logged in to change your username' }); - try { - const brews = await HomebrewModel.getByUser(username, true, ['authors']); - const renamePromises = brews.map(async (brew)=>{ - const updatedAuthors = brew.authors.map((author)=>author === username ? newUsername : author - ); - return HomebrewModel.updateOne( - { _id: brew._id }, - { $set: { authors: updatedAuthors } } - ); - }); - await Promise.all(renamePromises); - - return res.json({ success: true, message: `Brews for ${username} renamed to ${newUsername}.` }); - } catch (error) { - console.error('Error renaming brews:', error); - return res.status(500).json({ error: 'Failed to rename brews.' }); - } -}); - -//Edit Page -app.get('/edit/:id', asyncHandler(getBrew('edit')), asyncHandler(async(req, res, next)=>{ - req.brew = req.brew.toObject ? req.brew.toObject() : req.brew; - - req.userThemes = await(getUsersBrewThemes(req.account?.username)); - - req.ogMeta = { ...defaultMetaTags, - title : req.brew.title || 'Untitled Brew', - description : req.brew.description || 'No description.', - image : req.brew.thumbnail || defaultMetaTags.image, - locale : req.brew.lang, - type : 'article' - }; - - sanitizeBrew(req.brew, 'edit'); - splitTextStyleAndMetadata(req.brew); - res.header('Cache-Control', 'no-cache, no-store'); //reload the latest saved brew when pressing back button, not the cached version before save. - return next(); -})); - -//New Page from ID -app.get('/new/:id', asyncHandler(getBrew('share')), asyncHandler(async(req, res, next)=>{ - sanitizeBrew(req.brew, 'share'); - splitTextStyleAndMetadata(req.brew); - const brew = { - shareId : req.brew.shareId, - title : `CLONE - ${req.brew.title}`, - text : req.brew.text, - style : req.brew.style, - renderer : req.brew.renderer, - theme : req.brew.theme, - tags : req.brew.tags, - snippets : req.brew.snippets - }; - req.brew = _.defaults(brew, DEFAULT_BREW); - - req.userThemes = await(getUsersBrewThemes(req.account?.username)); - - req.ogMeta = { ...defaultMetaTags, - title : 'New', - description : 'Start crafting your homebrew on the Homebrewery!' - }; - - return next(); -})); - -//New Page -app.get('/new', asyncHandler(async(req, res, next)=>{ - req.userThemes = await(getUsersBrewThemes(req.account?.username)); - - req.ogMeta = { ...defaultMetaTags, - title : 'New', - description : 'Start crafting your homebrew on the Homebrewery!' - }; - - return next(); -})); - - -const shareEmbedCommon = async (req)=>{ - const { brew } = req; - req.ogMeta = { ...defaultMetaTags, - title : `${req.brew.title || 'Untitled Brew'} - ${req.brew.authors[0] || 'No author.'}`, - description : req.brew.description || 'No description.', - image : req.brew.thumbnail || defaultMetaTags.image, - type : 'article' - }; - - // increase visitor view count, do not include visits by author(s) - if(!brew.authors.includes(req.account?.username)){ - if(req.params.id.length > 12 && !brew._id) { - const googleId = brew.googleId; - const shareId = brew.shareId; - await GoogleActions.increaseView(googleId, shareId, 'share', brew) - .catch((err)=>{next(err);}); - } else { - await HomebrewModel.increaseView({ shareId: brew.shareId }); + return res.json({ success: true, message: `Brews for ${username} renamed to ${newUsername}.` }); + } catch (error) { + console.error('Error renaming brews:', error); + return res.status(500).json({ error: 'Failed to rename brews.' }); } + }); + + //Edit Page + app.get('/edit/:id', asyncHandler(getBrew('edit')), asyncHandler(async(req, res, next)=>{ + req.brew = req.brew.toObject ? req.brew.toObject() : req.brew; + + req.userThemes = await(getUsersBrewThemes(req.account?.username)); + + req.ogMeta = { ...defaultMetaTags, + title : req.brew.title || 'Untitled Brew', + description : req.brew.description || 'No description.', + image : req.brew.thumbnail || defaultMetaTags.image, + locale : req.brew.lang, + type : 'article' + }; + + sanitizeBrew(req.brew, 'edit'); + splitTextStyleAndMetadata(req.brew); + res.header('Cache-Control', 'no-cache, no-store'); //reload the latest saved brew when pressing back button, not the cached version before save. + return next(); + })); + + //New Page from ID + app.get('/new/:id', asyncHandler(getBrew('share')), asyncHandler(async(req, res, next)=>{ + sanitizeBrew(req.brew, 'share'); + splitTextStyleAndMetadata(req.brew); + const brew = { + shareId : req.brew.shareId, + title : `CLONE - ${req.brew.title}`, + text : req.brew.text, + style : req.brew.style, + renderer : req.brew.renderer, + theme : req.brew.theme, + tags : req.brew.tags, + snippets : req.brew.snippets + }; + req.brew = _.defaults(brew, DEFAULT_BREW); + + req.userThemes = await(getUsersBrewThemes(req.account?.username)); + + req.ogMeta = { ...defaultMetaTags, + title : 'New', + description : 'Start crafting your homebrew on the Homebrewery!' + }; + + return next(); + })); + + //New Page + app.get('/new', asyncHandler(async(req, res, next)=>{ + req.userThemes = await(getUsersBrewThemes(req.account?.username)); + + req.ogMeta = { ...defaultMetaTags, + title : 'New', + description : 'Start crafting your homebrew on the Homebrewery!' + }; + + return next(); + })); + + + const shareEmbedCommon = async(req)=>{ + + const { brew } = req; + req.ogMeta = { ...defaultMetaTags, + title : `${req.brew.title || 'Untitled Brew'} - ${req.brew.authors[0] || 'No author.'}`, + description : req.brew.description || 'No description.', + image : req.brew.thumbnail || defaultMetaTags.image, + type : 'article' + }; + + // increase visitor view count, do not include visits by author(s) + if(!brew.authors.includes(req.account?.username)){ + if(req.params.id.length > 12 && !brew._id) { + const googleId = brew.googleId; + const shareId = brew.shareId; + await GoogleActions.increaseView(googleId, shareId, 'share', brew) + .catch((err)=>{next(err);}); + } else { + await HomebrewModel.increaseView({ shareId: brew.shareId }); + } + }; + + brew.authors.includes(req.account?.username) ? sanitizeBrew(req.brew, 'shareAuthor') : sanitizeBrew(req.brew, 'share'); + splitTextStyleAndMetadata(req.brew); }; - brew.authors.includes(req.account?.username) ? sanitizeBrew(req.brew, 'shareAuthor') : sanitizeBrew(req.brew, 'share'); - splitTextStyleAndMetadata(req.brew); -}; + //Share Page + app.get('/share/:id', dbCheck, asyncHandler(getBrew('share')), asyncHandler(async (req, res, next)=>{ + shareEmbedCommon(req); + return next(); + })); -//Share Page -app.get('/share/:id', dbCheck, asyncHandler(getBrew('share')), asyncHandler(async (req, res, next)=>{ - shareEmbedCommon(req); - return next(); -})); + //Embed Page - More work will be done on this later... + app.get('/embed/:id', dbCheck, asyncHandler(getBrew('share')), asyncHandler(async (req, res, next)=>{ + shareEmbedCommon(req); + return next(); + })); -//Embed Page -app.get('/embed/:id', dbCheck, asyncHandler(getBrew('share')), asyncHandler(async (req, res, next)=>{ - shareEmbedCommon(req); - return next(); -})); + //Account Page + app.get('/account', dbCheck, asyncHandler(async (req, res, next)=>{ + const data = {}; + data.title = 'Account Information Page'; -//Account Page -app.get('/account', dbCheck, asyncHandler(async (req, res, next)=>{ - const data = {}; - data.title = 'Account Information Page'; + if(!req.account) { + res.set('WWW-Authenticate', 'Bearer realm="Authorization Required"'); + const error = new Error('No valid account'); + error.status = 401; + error.HBErrorCode = '50'; + error.page = data.title; + return next(error); + }; - if(!req.account) { - res.set('WWW-Authenticate', 'Bearer realm="Authorization Required"'); - const error = new Error('No valid account'); - error.status = 401; - error.HBErrorCode = '50'; - error.page = data.title; - return next(error); - }; + let auth; + let googleCount = []; + if(req.account) { + if(req.account.googleId) { + auth = await GoogleActions.authCheck(req.account, res, false); - let auth; - let googleCount = []; - if(req.account) { - if(req.account.googleId) { - auth = await GoogleActions.authCheck(req.account, res, false); - - googleCount = await GoogleActions.listGoogleBrews(auth) + googleCount = await GoogleActions.listGoogleBrews(auth) .catch((err)=>{ console.error(err); }); - } + } - const query = { authors: req.account.username, googleId: { $exists: false } }; - const mongoCount = await HomebrewModel.countDocuments(query) + const query = { authors: req.account.username, googleId: { $exists: false } }; + const mongoCount = await HomebrewModel.countDocuments(query) .catch((err)=>{ console.log(err); return 0; }); - data.accountDetails = { - username : req.account.username, - issued : req.account.issued, - googleId : Boolean(req.account.googleId), - authCheck : Boolean(req.account.googleId && auth?.credentials.access_token), - mongoCount : mongoCount, - googleCount : googleCount?.length + data.accountDetails = { + username : req.account.username, + issued : req.account.issued, + googleId : Boolean(req.account.googleId), + authCheck : Boolean(req.account.googleId && auth?.credentials.access_token), + mongoCount : mongoCount, + googleCount : googleCount?.length + }; + } + + req.brew = data; + + req.ogMeta = { ...defaultMetaTags, + title : `Account Page`, + description : null }; - } - req.brew = data; + return next(); + })); - req.ogMeta = { ...defaultMetaTags, - title : `Account Page`, - description : null - }; - - return next(); -})); - -// Local only -if(isLocalEnvironment){ + // Local only + if(isLocalEnvironment){ // Login - app.post('/local/login', (req, res)=>{ - const username = req.body.username; - if(!username) return; + app.post('/local/login', (req, res)=>{ + const username = req.body.username; + if(!username) return; - const payload = jwt.encode({ username: username, issued: new Date }, config.get('secret')); - return res.json(payload); - }); -} - -// Add Static Local Paths -app.use('/staticImages', express.static(config.get('hb_images') && fs.existsSync(config.get('hb_images')) ? config.get('hb_images') :'staticImages')); -app.use('/staticFonts', express.static(config.get('hb_fonts') && fs.existsSync(config.get('hb_fonts')) ? config.get('hb_fonts'):'staticFonts')); - -//Vault Page -app.get('/vault', asyncHandler(async(req, res, next)=>{ - req.ogMeta = { ...defaultMetaTags, - title : 'The Vault', - description : 'Search for Brews' - }; - return next(); -})); - -//Send rendered page -app.use(asyncHandler(async (req, res, next)=>{ - if(!req.route) return res.redirect('/'); // Catch-all for invalid routes - - const page = await renderPage(req, res); - if(!page) return; - res.send(page); -})); - -//Render the page -const renderPage = async (req, res)=>{ - // Create configuration object - const configuration = { - local : isLocalEnvironment, - publicUrl : config.get('publicUrl') ?? '', - baseUrl : `${req.protocol}://${req.get('host')}`, - environment : nodeEnv, - deployment : config.get('heroku_app_name') ?? '' - }; - const props = { - version : version, - url : req.customUrl || req.originalUrl, - brew : req.brew, - brews : req.brews, - googleBrews : req.googleBrews, - account : req.account, - config : configuration, - ogMeta : req.ogMeta, - userThemes : req.userThemes - }; - const title = req.brew ? req.brew.title : ''; - const page = await templateFn('homebrew', title, props) - .catch((err)=>{ - console.log(err); + const payload = jwt.encode({ username: username, issued: new Date }, config.get('secret')); + return res.json(payload); }); - return page; -}; - -//v=====----- Error-Handling Middleware -----=====v// -//Format Errors as plain objects so all fields will appear in the string sent -const formatErrors = (key, value)=>{ - if(value instanceof Error) { - const error = {}; - Object.getOwnPropertyNames(value).forEach(function (key) { - error[key] = value[key]; - }); - return error; } - return value; -}; -const getPureError = (error)=>{ - return JSON.parse(JSON.stringify(error, formatErrors)); -}; + // Add Static Local Paths + app.use('/staticImages', express.static(config.get('hb_images') && fs.existsSync(config.get('hb_images')) ? config.get('hb_images') :'staticImages')); + app.use('/staticFonts', express.static(config.get('hb_fonts') && fs.existsSync(config.get('hb_fonts')) ? config.get('hb_fonts'):'staticFonts')); -app.use(async (err, req, res, next)=>{ - err.originalUrl = req.originalUrl; - console.error(err); + //Vault Page + app.get('/vault', asyncHandler(async(req, res, next)=>{ + req.ogMeta = { ...defaultMetaTags, + title : 'The Vault', + description : 'Search for Brews' + }; + return next(); + })); - if(err.originalUrl?.startsWith('/api')) { + //Send rendered page + app.use(asyncHandler(async (req, res, next)=>{ + if(!req.route) return res.redirect('/'); // Catch-all for invalid routes + + const page = await renderPage(req, res); + if(!page) return; + res.send(page); + })); + + //Render the page + const renderPage = async (req, res)=>{ + + // Create configuration object + const configuration = { + local : isLocalEnvironment, + publicUrl : config.get('publicUrl') ?? '', + baseUrl : `${req.protocol}://${req.get('host')}`, + environment : nodeEnv, + deployment : config.get('heroku_app_name') ?? '' + }; + const props = { + version : version, + url : req.customUrl || req.originalUrl, + brew : req.brew, + brews : req.brews, + googleBrews : req.googleBrews, + account : req.account, + config : configuration, + ogMeta : req.ogMeta, + userThemes : req.userThemes + }; + + const ogTags = []; + const ogMeta = req.ogMeta ?? {}; + Object.entries(ogMeta).forEach(([key, value])=>{ + if(!value) return; + const tag = ``; + ogTags.push(tag); + }); + const ogMetaTags = ogTags.join('\n'); + + const htmlPath = isProd ? path.resolve('build', 'index.html') : path.resolve('index.html'); + let html = fs.readFileSync(htmlPath, 'utf-8'); + + if(!isProd && vite?.transformIndexHtml) { + html = await vite.transformIndexHtml(req.originalUrl, html); + } + + html = html.replace( + '', + `\n\n${ogMetaTags}` + ); + + return html; + }; + + //v=====----- Error-Handling Middleware -----=====v// + //Format Errors as plain objects so all fields will appear in the string sent + const formatErrors = (key, value)=>{ + if(value instanceof Error) { + const error = {}; + Object.getOwnPropertyNames(value).forEach(function (key) { + error[key] = value[key]; + }); + return error; + } + return value; + }; + + const getPureError = (error)=>{ + return JSON.parse(JSON.stringify(error, formatErrors)); + }; + + app.use(async (err, req, res, next)=>{ + err.originalUrl = req.originalUrl; + console.error(err); + + if(err.originalUrl?.startsWith('/api')) { // console.log('API error'); - res.status(err.status || err.response?.status || 500).send(err); - return; - } + res.status(err.status || err.response?.status || 500).send(err); + return; + } - // console.log('non-API error'); - const status = err.status || err.code || 500; + // console.log('non-API error'); + const status = err.status || err.code || 500; - req.ogMeta = { ...defaultMetaTags, - title : 'Error Page', - description : 'Something went wrong!' - }; - req.brew = { - ...err, - title : 'Error - Something went wrong!', - text : err.errors?.map((error)=>{return error.message;}).join('\n\n') || err.message || 'Unknown error!', - status : status, - HBErrorCode : err.HBErrorCode ?? '00', - pureError : getPureError(err) - }; - req.customUrl= '/error'; + req.ogMeta = { ...defaultMetaTags, + title : 'Error Page', + description : 'Something went wrong!' + }; + req.brew = { + ...err, + title : 'Error - Something went wrong!', + text : err.errors?.map((error)=>{return error.message;}).join('\n\n') || err.message || 'Unknown error!', + status : status, + HBErrorCode : err.HBErrorCode ?? '00', + pureError : getPureError(err) + }; + req.customUrl= '/error'; - const page = await renderPage(req, res); - if(!page) return; - res.send(page); -}); + const page = await renderPage(req, res); + if(!page) return; + res.send(page); + }); -app.use((req, res)=>{ - if(!res.headersSent) { - console.error('Headers have not been sent, responding with a server error.', req.url); - res.status(500).send('An error occurred and the server did not send a response. The error has been logged, please note the time this occurred and report this issue.'); - } -}); -//^=====--------------------------------------=====^// + app.use((req, res)=>{ + if(!res.headersSent) { + console.error('Headers have not been sent, responding with a server error.', req.url); + res.status(500).send('An error occurred and the server did not send a response. The error has been logged, please note the time this occurred and report this issue.'); + } + }); + //^=====--------------------------------------=====^// -export default app; + return app; +} diff --git a/server/brewDefaults.js b/server/brewDefaults.js index 11a84b9e9..501914735 100644 --- a/server/brewDefaults.js +++ b/server/brewDefaults.js @@ -14,7 +14,6 @@ const DEFAULT_BREW = { theme : '5ePHB', authors : [], tags : [], - systems : [], lang : 'en', thumbnail : '', views : 0, diff --git a/server/googleActions.js b/server/googleActions.js index b13ca11b9..d50549051 100644 --- a/server/googleActions.js +++ b/server/googleActions.js @@ -151,7 +151,6 @@ const GoogleActions = { description : file.description, views : parseInt(file.properties.views), published : file.properties.published ? file.properties.published == 'true' : false, - systems : [], lang : file.properties.lang, thumbnail : file.properties.thumbnail, webViewLink : file.webViewLink @@ -298,7 +297,6 @@ const GoogleActions = { text : file.data, description : obj.data.description, - systems : obj.data.properties.systems ? obj.data.properties.systems.split(',') : [], authors : [], lang : obj.data.properties.lang, published : obj.data.properties.published ? obj.data.properties.published == 'true' : false, diff --git a/server/homebrew.api.js b/server/homebrew.api.js index 4d4f5a911..04c6507e8 100644 --- a/server/homebrew.api.js +++ b/server/homebrew.api.js @@ -31,6 +31,27 @@ const isStaticTheme = (renderer, themeName)=>{ // }); // }; + +const migrateSystemsToTags = (brew) => { + if (!('systems' in brew)) return brew; + + if (!Array.isArray(brew.systems) || brew.systems.length === 0) { + brew.systems = undefined; + return brew; + } + const systemMap = { + '5e': 'system:D&D 5e', + '4e': 'system:D&D 4e', + '3.5e': 'system:D&D 3.5e', + 'Pathfinder': 'system:Pathfinder 2e' + }; + const systemTags = brew.systems.map(s => systemMap[s]); + brew.tags = _.uniq([...(brew.tags || []), ...systemTags]); + + brew.systems = undefined; + return brew; +}; + const MAX_TITLE_LENGTH = 100; const api = { @@ -167,7 +188,10 @@ const api = { stub.renderer = stub.renderer || undefined; // Clear empty strings stub = _.defaults(stub, DEFAULT_BREW_LOAD); // Fill in blank fields - req.brew = stub; + + + const fixedStub = migrateSystemsToTags(stub); + req.brew = fixedStub; next(); }; }, @@ -193,7 +217,7 @@ const api = { `\`\`\`\n\n` + `${text}`; } - const metadata = _.pick(brew, ['title', 'description', 'tags', 'systems', 'renderer', 'theme']); + const metadata = _.pick(brew, ['title', 'description', 'tags', 'renderer', 'theme']); const snippetsArray = brewSnippetsToJSON('brew_snippets', brew.snippets, null, false).snippets; metadata.snippets = snippetsArray.length > 0 ? snippetsArray : undefined; text = `\`\`\`metadata\n` + @@ -392,6 +416,9 @@ const api = { } let brew = _.assign(brewFromServer, brewFromClient); + + migrateSystemsToTags(brew); + brew.title = brew.title.trim(); brew.description = brew.description.trim() || ''; brew.text = api.mergeBrewText(brew); @@ -481,7 +508,7 @@ const api = { await HomebrewModel.deleteOne({ editId: id }); return next(); } - throw(err); + throw (err); } let brew = req.brew; diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 0a6d1d452..05ae8c51a 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -63,7 +63,6 @@ describe('Tests for api', ()=>{ title : 'some title', description : 'this is a description', tags : ['something', 'fun'], - systems : ['D&D 5e'], lang : 'en', renderer : 'v3', theme : 'phb', @@ -351,7 +350,6 @@ describe('Tests for api', ()=>{ renderer : 'legacy', lang : 'en', shareId : undefined, - systems : [], tags : [], theme : '5ePHB', thumbnail : '', @@ -390,7 +388,6 @@ describe('Tests for api', ()=>{ title : 'some title', description : 'this is a description', tags : ['something', 'fun'], - systems : ['D&D 5e'], renderer : 'v3', theme : 'phb', googleId : '12345' @@ -402,8 +399,6 @@ description: this is a description tags: - something - fun -systems: - - D&D 5e renderer: v3 theme: phb @@ -419,7 +414,6 @@ brew`); title : 'some title', description : 'this is a description', tags : ['something', 'fun'], - systems : ['D&D 5e'], renderer : 'v3', theme : 'phb', googleId : '12345' @@ -431,8 +425,6 @@ description: this is a description tags: - something - fun -systems: - - D&D 5e renderer: v3 theme: phb @@ -463,7 +455,6 @@ brew`); expect(sent).toEqual(googleBrew); expect(result.tags).toBeUndefined(); - expect(result.systems).toBeUndefined(); expect(result.published).toBeUndefined(); expect(result.authors).toBeUndefined(); expect(result.owner).toBeUndefined(); @@ -558,7 +549,6 @@ brew`); lang : 'en', shareId : expect.any(String), style : undefined, - systems : [], tags : [], text : undefined, textBin : expect.objectContaining({}), @@ -618,7 +608,6 @@ brew`); shareId : expect.any(String), googleId : expect.any(String), style : undefined, - systems : [], tags : [], text : undefined, textBin : undefined, @@ -1076,7 +1065,6 @@ brew`); 'title: title\n' + 'description: description\n' + 'tags: [ \'tag a\' , \'tag b\' ]\n' + - 'systems: [ test system ]\n' + 'renderer: legacy\n' + 'theme: 5ePHB\n' + 'lang: en\n' + @@ -1097,8 +1085,6 @@ brew`); // Metadata expect(testBrew.title).toEqual('title'); expect(testBrew.description).toEqual('description'); - expect(testBrew.tags).toEqual(['tag a', 'tag b']); - expect(testBrew.systems).toEqual(['test system']); expect(testBrew.renderer).toEqual('legacy'); expect(testBrew.theme).toEqual('5ePHB'); expect(testBrew.lang).toEqual('en'); @@ -1107,19 +1093,6 @@ brew`); // Text expect(testBrew.text).toEqual('text\n'); }); - - it('convert tags string to array', async ()=>{ - const testBrew = { - text : '```metadata\n' + - 'tags: tag a\n' + - '```\n\n' - }; - - splitTextStyleAndMetadata(testBrew); - - // Metadata - expect(testBrew.tags).toEqual(['tag a']); - }); }); describe('updateBrew', ()=>{ diff --git a/server/homebrew.model.js b/server/homebrew.model.js index ff371ee42..b3d7702ce 100644 --- a/server/homebrew.model.js +++ b/server/homebrew.model.js @@ -15,7 +15,7 @@ const HomebrewSchema = mongoose.Schema({ description : { type: String, default: '' }, tags : { type: [String], index: true }, - systems : [String], + systems : { type: [String], default: undefined }, lang : { type: String, default: 'en', index: true }, renderer : { type: String, default: '', index: true }, authors : { type: [String], index: true }, diff --git a/shared/helpers.js b/shared/helpers.js index 91ad3bfb9..17e2a2e93 100644 --- a/shared/helpers.js +++ b/shared/helpers.js @@ -27,7 +27,7 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=nul userSnippets.push({ name : snippetName, icon : '', - gen : snipSplit[snips + 1], + gen : snipSplit[snips + 1].replace(/\n$/, ''), }); } } @@ -52,7 +52,7 @@ const brewSnippetsToJSON = (menuTitle, userBrewSnippets, themeBundleSnippets=nul if(snippetName.length != 0) { const subSnip = { name : snippetName, - gen : snipSplit[snips + 1], + gen : snipSplit[snips + 1].replace(/\n$/, ''), }; // if(full) subSnip.icon = ''; userSnippets.push(subSnip); @@ -99,7 +99,7 @@ const splitTextStyleAndMetadata = (brew)=>{ const index = brew.text.indexOf('\n```\n\n'); const metadataSection = brew.text.slice(11, index + 1); const metadata = yaml.load(metadataSection); - Object.assign(brew, _.pick(metadata, ['title', 'description', 'tags', 'systems', 'renderer', 'theme', 'lang'])); + Object.assign(brew, _.pick(metadata, ['title', 'description', 'renderer', 'theme', 'lang'])); brew.snippets = yamlSnippetsToText(_.pick(metadata, ['snippets']).snippets || ''); brew.text = brew.text.slice(index + 6); } diff --git a/shared/markdown.js b/shared/markdown.js index adb058042..09a6b37e3 100644 --- a/shared/markdown.js +++ b/shared/markdown.js @@ -1,4 +1,4 @@ -/* eslint-disable max-depth */ + /* eslint-disable max-lines */ import _ from 'lodash'; import { marked as Marked } from 'marked'; diff --git a/shared/naturalcrit/styles/core.less b/shared/naturalcrit/styles/core.less index 02db5db18..3ef75144d 100644 --- a/shared/naturalcrit/styles/core.less +++ b/shared/naturalcrit/styles/core.less @@ -1,16 +1,16 @@ -@import 'naturalcrit/styles/reset.less'; -//@import 'naturalcrit/styles/elements.less'; -@import 'naturalcrit/styles/animations.less'; -@import 'naturalcrit/styles/colors.less'; -@import 'naturalcrit/styles/tooltip.less'; +@import './reset.less'; +//@import './elements.less'; +@import './animations.less'; +@import './colors.less'; +@import './tooltip.less'; @font-face { font-family : 'CodeLight'; - src : data-uri('naturalcrit/styles/CODE Light.otf') format('opentype'); + src : url('./CODE Light.otf') format('opentype'); } @font-face { font-family : 'CodeBold'; - src : data-uri('naturalcrit/styles/CODE Bold.otf') format('opentype'); + src : url('./CODE Bold.otf') format('opentype'); } html,body, #reactRoot { height : 100vh; diff --git a/tests/html/safeHTML.test.js b/tests/html/safeHTML.test.js index 208101f9a..0b5b4c169 100644 --- a/tests/html/safeHTML.test.js +++ b/tests/html/safeHTML.test.js @@ -1,6 +1,6 @@ import globalJsdom from 'jsdom-global'; globalJsdom(); -import { safeHTML } from '../../client/homebrew/brewRenderer/safeHTML'; +import safeHTML from '../../client/homebrew/brewRenderer/safeHTML'; test('Exit if no document', function() { const doc = document; diff --git a/tests/markdown/basic.test.js b/tests/markdown/basic.test.js index ddceb9197..f2405d0d8 100644 --- a/tests/markdown/basic.test.js +++ b/tests/markdown/basic.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; test('Processes the markdown within an HTML block if its just a class wrapper', function() { const source = '
*Bold text*
'; diff --git a/tests/markdown/definition-lists.test.js b/tests/markdown/definition-lists.test.js index 12499d559..35ad12ef7 100644 --- a/tests/markdown/definition-lists.test.js +++ b/tests/markdown/definition-lists.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Inline Definition Lists', ()=>{ test('No Term 1 Definition', function() { diff --git a/tests/markdown/emojis.test.js b/tests/markdown/emojis.test.js index 5f0e102c9..072de10f9 100644 --- a/tests/markdown/emojis.test.js +++ b/tests/markdown/emojis.test.js @@ -1,4 +1,4 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; import dedent from 'dedent'; // Marked.js adds line returns after closing tags on some default tokens. diff --git a/tests/markdown/hard-breaks.test.js b/tests/markdown/hard-breaks.test.js index 068b2053a..1f48f8f1e 100644 --- a/tests/markdown/hard-breaks.test.js +++ b/tests/markdown/hard-breaks.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Hard Breaks', ()=>{ test('Single Break', function() { diff --git a/tests/markdown/mustache-syntax.test.js b/tests/markdown/mustache-syntax.test.js index 8562ae412..95ca2f58d 100644 --- a/tests/markdown/mustache-syntax.test.js +++ b/tests/markdown/mustache-syntax.test.js @@ -1,7 +1,7 @@ /* eslint-disable max-lines */ import dedent from 'dedent'; -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; // Marked.js adds line returns after closing tags on some default tokens. // This removes those line returns for comparison sake. diff --git a/tests/markdown/non-breaking-spaces.test.js b/tests/markdown/non-breaking-spaces.test.js index 9da59b047..731d0546e 100644 --- a/tests/markdown/non-breaking-spaces.test.js +++ b/tests/markdown/non-breaking-spaces.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Non-Breaking Spaces Interactions', ()=>{ test('I am actually a single-line definition list!', function() { diff --git a/tests/markdown/paragraph-justification.test.js b/tests/markdown/paragraph-justification.test.js index f5a5b12ab..6ce454623 100644 --- a/tests/markdown/paragraph-justification.test.js +++ b/tests/markdown/paragraph-justification.test.js @@ -1,6 +1,6 @@ -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; describe('Justification', ()=>{ test('Left Justify', function() { diff --git a/tests/markdown/variables.test.js b/tests/markdown/variables.test.js index 49cd333c8..884553703 100644 --- a/tests/markdown/variables.test.js +++ b/tests/markdown/variables.test.js @@ -1,7 +1,7 @@ /* eslint-disable max-lines */ import dedent from 'dedent'; -import Markdown from 'markdown.js'; +import Markdown from '../../shared/markdown.js'; // Marked.js adds line returns after closing tags on some default tokens. // This removes those line returns for comparison sake. diff --git a/tests/routes/static-pages.test.js b/tests/routes/static-pages.test.js index ebfa48dd4..2741b8d70 100644 --- a/tests/routes/static-pages.test.js +++ b/tests/routes/static-pages.test.js @@ -1,27 +1,32 @@ import supertest from 'supertest'; -import HBApp from 'app.js'; +import createApp from '../../server/app.js'; -// Mimic https responses to avoid being redirected all the time -const app = supertest.agent(HBApp).set('X-Forwarded-Proto', 'https'); +let app; +let request; + +beforeAll(async ()=>{ + app = await createApp(); + request = supertest.agent(app).set('X-Forwarded-Proto', 'https'); +}); describe('Tests for static pages', ()=>{ - it('Home page works', ()=>{ - return app.get('/').expect(200); + it('Home page works', async ()=>{ + await request.get('/').expect(200); }); - it('Home page legacy works', ()=>{ - return app.get('/legacy').expect(200); + it('Home page legacy works', async ()=>{ + await request.get('/legacy').expect(200); }); - it('Changelog page works', ()=>{ - return app.get('/changelog').expect(200); + it('Changelog page works', async ()=>{ + await request.get('/changelog').expect(200); }); - it('FAQ page works', ()=>{ - return app.get('/faq').expect(200); + it('FAQ page works', async ()=>{ + await request.get('/faq').expect(200); }); - it('robots.txt works', ()=>{ - return app.get('/robots.txt').expect(200); + it('robots.txt works', async ()=>{ + await request.get('/robots.txt').expect(200); }); -}); +}); \ No newline at end of file diff --git a/themes/Legacy/5ePHB/snippets.js b/themes/Legacy/5ePHB/snippets.js index a6a9dbe88..5bf74b4ca 100644 --- a/themes/Legacy/5ePHB/snippets.js +++ b/themes/Legacy/5ePHB/snippets.js @@ -1,12 +1,12 @@ /* eslint-disable max-lines */ -import MagicGen from './snippets/magic.gen.js'; +import MagicGen from './snippets/magic.gen.js'; import ClassTableGen from './snippets/classtable.gen.js'; import MonsterBlockGen from './snippets/monsterblock.gen.js'; import ClassFeatureGen from './snippets/classfeature.gen.js'; import CoverPageGen from './snippets/coverpage.gen.js'; import TableOfContentsGen from './snippets/tableOfContents.gen.js'; -import dedent from 'dedent'; +import dedent from 'dedent'; export default [ diff --git a/themes/Legacy/5ePHB/snippets/classfeature.gen.js b/themes/Legacy/5ePHB/snippets/classfeature.gen.js index b92d527f9..70085d647 100644 --- a/themes/Legacy/5ePHB/snippets/classfeature.gen.js +++ b/themes/Legacy/5ePHB/snippets/classfeature.gen.js @@ -1,6 +1,6 @@ import _ from 'lodash'; -export default function(classname){ +function classFeatureGen(classname) { classname = _.sample(['archivist', 'fancyman', 'linguist', 'fletcher', 'notary', 'berserker-typist', 'fishmongerer', 'manicurist', 'haberdasher', 'concierge']); @@ -49,4 +49,6 @@ export default function(classname){ `- ${_.sample(['10 lint fluffs', '1 button', 'a cherished lost sock'])}`, '\n\n\n' ].join('\n'); -}; +} + +export default classFeatureGen; diff --git a/themes/Legacy/5ePHB/snippets/coverpage.gen.js b/themes/Legacy/5ePHB/snippets/coverpage.gen.js index 0cd0e50d5..9c2de2943 100644 --- a/themes/Legacy/5ePHB/snippets/coverpage.gen.js +++ b/themes/Legacy/5ePHB/snippets/coverpage.gen.js @@ -98,7 +98,7 @@ const subtitles = [ ]; -export default ()=>{ +function coverPageGen() { return ``); + return null; + }, +}; + +export const Inject = ({ tag, children, ...props })=>{ + useEffect(()=>{ + injectTag(tag, props, children); + }, []); + return null; +}; + +export const generate = ()=>Object.values(NamedTags).concat(UnnamedTags).join('\n'); + +export const flush = ()=>{ + NamedTags = {}; + UnnamedTags = []; +}; + +export const Meta = HeadComponents.Meta; + +export default { + Inject, + ...HeadComponents, + generate, + flush, +};